From ecc8b209dc0fd9a7363d5ea51b8885e7a8987b40 Mon Sep 17 00:00:00 2001 From: noname08662 <178931709+noname08662@users.noreply.github.com> Date: Tue, 19 Nov 2024 19:10:12 +0200 Subject: [PATCH] Add files via upload --- ElvUI_Extras.lua | 102 +- Libs/LibProcessable/LibProcessable.lua | 2 +- .../oUF_FloatingCombatFeedback.lua | 189 +- Locales/deDE.lua | 364 +- Locales/enUS.lua | 231 +- Locales/esMX.lua | 361 +- Locales/frFR.lua | 361 +- Locales/koKR.lua | 358 +- Locales/ptBR.lua | 385 +- Locales/ruRU.lua | 387 +- Locales/zhCN.lua | 356 +- Locales/zhTW.lua | 357 +- Modules/Blizzard/Automation.lua | 654 +- Modules/Blizzard/LootStyle.lua | 44 +- Modules/Blizzard/Misc.lua | 24 +- Modules/General/Bags.lua | 3027 ++++--- Modules/General/Chat.lua | 106 +- Modules/General/CustomCommands.lua | 404 +- Modules/General/Misc.lua | 54 +- Modules/General/Misc_data.lua | 2412 +++--- Modules/General/MoversPlus.lua | 4 +- Modules/General/QuestBar.lua | 26 +- Modules/Nameplates/Auras.lua | 86 +- Modules/Nameplates/ClassificationIcons.lua | 10 +- Modules/Nameplates/Cooldowns.lua | 14 +- Modules/Nameplates/GuildsTitles.lua | 625 +- Modules/Nameplates/GuildsTitles_data.lua | 6934 ++++++++--------- Modules/Nameplates/NameLevel.lua | 4 +- Modules/Nameplates/QuestIcons.lua | 10 +- Modules/Nameplates/StyleFilter.lua | 662 +- Modules/Unitframes/AuraBars.lua | 8 +- Modules/Unitframes/Auras.lua | 68 +- .../Unitframes/ClassificationIndicator.lua | 4 +- Modules/Unitframes/ColorFilter.lua | 775 +- Modules/Unitframes/Cooldowns.lua | 51 +- Modules/Unitframes/DRTracker.lua | 7 +- Modules/Unitframes/FCF.lua | 625 +- Modules/Unitframes/Misc.lua | 12 +- Optionals/Toolkit.lua | 10 +- 39 files changed, 11711 insertions(+), 8402 deletions(-) diff --git a/ElvUI_Extras.lua b/ElvUI_Extras.lua index 953d003..7299e12 100644 --- a/ElvUI_Extras.lua +++ b/ElvUI_Extras.lua @@ -380,8 +380,6 @@ if isAwesome then core:RegisterEvent('NAME_PLATE_CREATED', function(_, plate) local onShow, onHide = plate:GetScript("OnShow"), plate:GetScript("OnHide") NP:OnCreated(plate) - plate.UnitFrame.Name:FontTemplate() - plate.UnitFrame.Level:FontTemplate() plate:SetScript("OnShow", onShow) plate:SetScript("OnHide", onHide) end) @@ -510,12 +508,6 @@ if isAwesome then return core.hooks[NP].GetUnitInfo(self, frame) end - function core:OnShow(self, isConfig, dontHideHighlight) - if self.unit then - core.hooks[NP].OnShow(self, isConfig, dontHideHighlight) - end - end - function core:UnitDetailedThreatSituation(self, frame) local plate = frame:GetParent() if plate.unit then return UnitThreatSituation("player", plate.unit) end @@ -529,12 +521,12 @@ if isAwesome then --highest possible should be level 880 and we add 1 to all so 881 --local leveledCount = NP.CollectedFrameLevelCount or 1 --level = (frame.FrameLevelChanged*(40*NP.levelStep)) + (leveledCount*NP.levelStep) - local level = #GetNamePlates() + frame.FrameLevelChanged * 10 + local level = #GetNamePlates() + frame.FrameLevelChanged * 10 + 100 - frame:SetFrameLevel(level+1) + frame:SetFrameLevel(level) frame.Shadow:SetFrameLevel(level-1) - frame.Buffs:SetFrameLevel(level+1) - frame.Debuffs:SetFrameLevel(level+1) + frame.Buffs:SetFrameLevel(level) + frame.Debuffs:SetFrameLevel(level) frame.LevelHandled = true local targetPlate = GetNamePlateForUnit('target') @@ -546,11 +538,11 @@ if isAwesome then end end elseif frame.LevelHandled then - local level = #GetNamePlates() - frame:SetFrameLevel(level-1) - frame.Shadow:SetFrameLevel(level-2) - frame.Buffs:SetFrameLevel(level-1) - frame.Debuffs:SetFrameLevel(level-1) + local level = #GetNamePlates() + 100 + frame:SetFrameLevel(level) + frame.Shadow:SetFrameLevel(level-1) + frame.Buffs:SetFrameLevel(level) + frame.Debuffs:SetFrameLevel(level) frame.LevelHandled = false end end @@ -568,17 +560,24 @@ function core:OnShowHide(frame, health) if not healthEnabled[unitType] then local name = frame.Name for e, func in pairs(core.plateAnchoring) do - local element = frame[e] - local caller = func(unitType, frame) - if element then + local data, frames, target = func(unitType, frame) + local element = frame[e] or target + if data and element then local point, relativeTo, x, y - if caller then - point, relativeTo, x, y = caller.point, caller.relativeTo, caller.xOffset, caller.yOffset + if data then + point, relativeTo, x, y = data.point, data.relativeTo, data.xOffset, data.yOffset else point, _, relativeTo, x, y = frame:GetPoint() end element:ClearAllPoints() element:Point(point, health or name, relativeTo, x, y) + elseif frames then + for _, values in ipairs(frames or {}) do + for _, f in pairs(values or {}) do + f:ClearAllPoints() + f:Point(f.point or "CENTER", health or name, f.relativeTo or "CENTER", f.xOffset or 0, f.yOffset or 0) + end + end end end if unitType == "ENEMY_NPC" or unitType == "FRIENDLY_NPC" then @@ -609,6 +608,8 @@ core:SecureHook(NP, "OnCreated", function(self, plate) end end) end + frame.Name:FontTemplate() + frame.Level:FontTemplate() end end) @@ -817,7 +818,7 @@ do local func = "Update_"..type.."Frame" local groupFunc = "Update_"..type.."Frames" if (UF[func] or UF[groupFunc]) and not core:IsHooked(UF, UF[func] and func or groupFunc) then - core:SecureHook(UF, UF[func] and func or groupFunc, function(self, frame, db) + core:SecureHook(UF, UF[func] and func or groupFunc, function(self, frame, uf_db) if not taggedFrames[frame] then frame.updatesHandler = frame:CreateFontString(nil, "OVERLAY") frame.updatesHandler:FontTemplate() @@ -826,15 +827,15 @@ do taggedFrames[frame] = true - for _, func in ipairs(core.frameUpdates) do - func(self, frame, db) + for _, updateFunc in ipairs(core.frameUpdates) do + updateFunc(self, frame, uf_db) end elseif not updatePending then updatePending = true E_Delay(nil, 0.1, function() - for _, func in ipairs(core.frameUpdates) do - func(self, frame, db) + for _, updateFunc in ipairs(core.frameUpdates) do + updateFunc(self, frame, uf_db) end updatePending = false end) @@ -1602,7 +1603,7 @@ function core:Initialize() self.customColorAlpha = E.db.Extras.customColorAlpha self.customColorBeta = E.db.Extras.customColorBeta - core:SecureHook(NP, "UpdateAllFrame", function() + self:SecureHook(NP, "UpdateAllFrame", function() local FRIENDLY_NPC = healthEnabled["FRIENDLY_NPC"] local ENEMY_NPC = healthEnabled["ENEMY_NPC"] healthEnabled["FRIENDLY_NPC"] = NP.db.units["FRIENDLY_NPC"].health.enable @@ -1610,7 +1611,7 @@ function core:Initialize() if FRIENDLY_NPC ~= healthEnabled["FRIENDLY_NPC"] or ENEMY_NPC ~= healthEnabled["ENEMY_NPC"] then for frame in pairs(NP.VisiblePlates) do - core:OnShowHide(frame, frame.Health and frame.Health:IsVisible()) + self:OnShowHide(frame, frame.Health and frame.Health:IsVisible()) end end end) @@ -1625,7 +1626,7 @@ function core:Initialize() NP:UnregisterEvent("UNIT_NAME_UPDATE") for _, func in pairs({'UnitClass', 'GetUnitInfo', 'GetUnitByName', 'SetTargetFrame', - 'OnShow', 'ResetNameplateFrameLevel', 'UnitDetailedThreatSituation'}) do + 'ResetNameplateFrameLevel', 'UnitDetailedThreatSituation'}) do if not self:IsHooked(NP, func) then self:RawHook(NP, func) end end end @@ -1636,19 +1637,46 @@ function core:Initialize() module() end - local shadow_db = E.globalShadow + self:SecureHook(E, "SetMoversClampedToScreen", function(_, toggle) + E.globalShadow = nil + twipe(self.plateAnchoring) + self.reload = not toggle + if not toggle then + if self:IsHooked(NP, "UpdateAllFrame") then + self:Unhook(NP, "UpdateAllFrame") + end + elseif not self:IsHooked(NP, "UpdateAllFrame") then + self:SecureHook(NP, "UpdateAllFrame", function() + local FRIENDLY_NPC = healthEnabled["FRIENDLY_NPC"] + local ENEMY_NPC = healthEnabled["ENEMY_NPC"] + healthEnabled["FRIENDLY_NPC"] = NP.db.units["FRIENDLY_NPC"].health.enable + healthEnabled["ENEMY_NPC"] = NP.db.units["ENEMY_NPC"].health.enable + + if FRIENDLY_NPC ~= healthEnabled["FRIENDLY_NPC"] or ENEMY_NPC ~= healthEnabled["ENEMY_NPC"] then + for frame in pairs(NP.VisiblePlates) do + self:OnShowHide(frame, frame.Health and frame.Health:IsVisible()) + end + end + end) + end + for _, module in pairs(self.modules) do + module() + end + end) + local shadow_db = E.globalShadow if shadow_db then local M = E:GetModule("Misc") local chatBubbles = E.private.general.chatBubbles local createShadow = E.CreateGlobalShadow local size = shadow_db.size + local r, g, b, a = unpack(shadow_db.color) - createShadow(nil, shadow_db, _G["Minimap"]) + createShadow(nil, _G["Minimap"], size, r, g, b, a) for _, frame in ipairs({WorldFrame:GetChildren()}) do if frame.isSkinnedElvUI then - createShadow(nil, shadow_db, frame) + createShadow(nil, frame, size, r, g, b, a) if chatBubbles == "backdrop_noborder" then frame.globalShadow:SetOutside(frame.backdrop, size, size) elseif frame.globalShadow and chatBubbles == "nobackdrop" then @@ -1659,13 +1687,13 @@ function core:Initialize() if E.pendingShadowUpdate then for frame in pairs(E.pendingShadowUpdate) do - createShadow(nil, shadow_db, frame) + createShadow(nil, frame, size, r, g, b, a) end end if not self:IsHooked(M, "SkinBubble") then self:SecureHook(M, "SkinBubble", function(_, frame) - createShadow(nil, shadow_db, frame) + createShadow(nil, frame, size, r, g, b, a) if chatBubbles == "backdrop_noborder" then frame.globalShadow:SetOutside(frame.backdrop, size, size) elseif frame.globalShadow and chatBubbles == "nobackdrop" then @@ -1676,13 +1704,13 @@ function core:Initialize() if not self:IsHooked(NP, "StyleFrame") then self:SecureHook(NP, "StyleFrame", function(_, frame) - createShadow(nil, shadow_db, frame) + createShadow(nil, frame, size, r, g, b, a) end) end if not self:IsHooked(M, "SkinBubble") then self:SecureHook(M, "SkinBubble", function(_, frame) - createShadow(nil, shadow_db, frame) + createShadow(nil, frame, size, r, g, b, a) end) end diff --git a/Libs/LibProcessable/LibProcessable.lua b/Libs/LibProcessable/LibProcessable.lua index 90d2299..63838e3 100644 --- a/Libs/LibProcessable/LibProcessable.lua +++ b/Libs/LibProcessable/LibProcessable.lua @@ -349,7 +349,7 @@ end -- modified to work with 3.3.5 api local Handler = CreateFrame('Frame') Handler:RegisterEvent('SKILL_LINES_CHANGED') -Handler:SetScript('OnEvent', function(s, event) +Handler:SetScript('OnEvent', function() for i = 1, GetNumSkillLines() do local professionName, _, isHeader, skillLevel = GetSkillLineInfo(i) if not isHeader then diff --git a/Libs/oUF_FloatingCombatFeedback/oUF_FloatingCombatFeedback.lua b/Libs/oUF_FloatingCombatFeedback/oUF_FloatingCombatFeedback.lua index a42e0a3..2b2851c 100644 --- a/Libs/oUF_FloatingCombatFeedback/oUF_FloatingCombatFeedback.lua +++ b/Libs/oUF_FloatingCombatFeedback/oUF_FloatingCombatFeedback.lua @@ -119,8 +119,7 @@ local colors = { ["REFLECT" ] = rgb(255, 255, 255), ["RESIST" ] = rgb(255, 255, 255), ["WOUND" ] = rgb(179, 26, 26), - -- modified - ["AURA" ] = rgb(255, 255, 255), + ["AURA" ] = rgb(255, 255, 255), } local schoolColors = { @@ -158,6 +157,7 @@ local tryToColorBySchool = { ["REFLECT" ] = false, ["RESIST" ] = false, ["WOUND" ] = true, + ["AURA" ] = false, } local animations = { @@ -190,41 +190,48 @@ local animations = { } local animationsByEvent = { - ["ABSORB" ] = "fountain", - ["BLOCK" ] = "fountain", - ["DEFLECT" ] = "fountain", - ["DODGE" ] = "fountain", - ["ENERGIZE" ] = "fountain", - ["EVADE" ] = "fountain", - ["HEAL" ] = "fountain", - ["IMMUNE" ] = "fountain", - ["INTERRUPT"] = "fountain", - ["MISS" ] = "fountain", - ["PARRY" ] = "fountain", - ["REFLECT" ] = "fountain", - ["RESIST" ] = "fountain", - ["WOUND" ] = "fountain", - -- modified - ["AURA" ] = "fountain", + ["ABSORB" ] = {"fountain", true, true}, + ["BLOCK" ] = {"fountain", true, true}, + ["DEFLECT" ] = {"fountain", true, true}, + ["DODGE" ] = {"fountain", true, true}, + ["ENERGIZE" ] = {"fountain", true, true}, + ["EVADE" ] = {"fountain", true, true}, + ["HEAL" ] = {"fountain", true, true}, + ["IMMUNE" ] = {"fountain", true, true}, + ["INTERRUPT"] = {"fountain", true, true}, + ["MISS" ] = {"fountain", true, true}, + ["PARRY" ] = {"fountain", true, true}, + ["REFLECT" ] = {"fountain", true, true}, + ["RESIST" ] = {"fountain", true, true}, + ["WOUND" ] = {"fountain", true, true}, + ["AURA" ] = {"fountain", true, true}, } local animationsByFlag = { - ["ABSORB" ] = false, - ["BLOCK" ] = false, - ["CRITICAL"] = false, - ["CRUSHING"] = false, - ["GLANCING"] = false, - ["RESIST" ] = false, + ["ABSORB" ] = {false, false, false}, + ["BLOCK" ] = {false, false, false}, + ["CRITICAL" ] = {false, false, false}, + ["CRUSHING" ] = {false, false, false}, + ["GLANCING" ] = {false, false, false}, + ["RESIST" ] = {false, false, false}, + ["PERIODICWOUND"] = {false, false, false}, + ["NOFLAGWOUND" ] = {false, false, false}, + ["PERIODICHEAL" ] = {false, false, false}, + ["NOFLAGHEAL" ] = {false, false, false}, } local multipliersByFlag = { - ["" ] = 1, - ["ABSORB" ] = 0.75, - ["BLOCK" ] = 0.75, - ["CRITICAL"] = 1.25, - ["CRUSHING"] = 1.25, - ["GLANCING"] = 0.75, - ["RESIST" ] = 0.75, + ["" ] = 1, + ["ABSORB" ] = 0.75, + ["BLOCK" ] = 0.75, + ["CRITICAL" ] = 1.25, + ["CRUSHING" ] = 1.25, + ["GLANCING" ] = 0.75, + ["RESIST" ] = 0.75, + ["PERIODICWOUND"] = 0.75, + ["NOFLAGWOUND" ] = 1, + ["PERIODICHEAL" ] = 0.75, + ["NOFLAGHEAL" ] = 1, } local xOffsetsByAnimation = { @@ -266,14 +273,15 @@ end local function onUpdate(self, elapsed) for index, string in next, self.FeedbackToAnimate do - if string.elapsed >= self.scrollTime then + if string.elapsed >= string.scrollTime then removeString(self, index, string) else - string.progress = string.elapsed / self.scrollTime - string:SetPoint("CENTER", self, "CENTER", string:GetXY()) + string.progress = string.elapsed / string.scrollTime + local x, y = string:GetXY() + string:SetPoint(string.point, self, string.relativeTo, x + string.fontX, y + string.fontY) string.elapsed = string.elapsed + elapsed - string:SetAlpha(clamp(1 - (string.elapsed - self.fadeTime) / (self.scrollTime - self.fadeTime))) + string:SetAlpha(clamp(1 - (string.elapsed - string.fadeTime) / (string.scrollTime - string.fadeTime))) end end @@ -292,12 +300,11 @@ local function flush(self) end end --- modified -local iconFormats = { -} local function Update(self, _, unit, event, flag, amount, school, texture) if self.unit ~= unit then return end local element = self.FloatingCombatFeedback + local flagMult = element.multipliersByFlag[flag] + if event ~= "BUFF" and event ~= "DEBUFF" and not flagMult then return end local unitGUID = UnitGUID(unit) if unitGUID ~= element.unitGUID then @@ -305,17 +312,14 @@ local function Update(self, _, unit, event, flag, amount, school, texture) element.unitGUID = unitGUID end - local animation = element.animationsByEvent[event] - if not animation then return end - - animation = element.animationsByFlag[flag] or animation + local animation, fontData = element.animationsByEvent[event], element.fontData[event] + if not animation or not fontData then return end local color = element.tryToColorBySchool[event] and element.schoolColors[school] or element.colors[event] - local text if event == "WOUND" then - if amount ~= 0 then + if amount ~= 0 then text = element.abbreviateNumbers and AbbreviateNumbers(amount) or BreakUpLargeNumbers(amount) elseif flag ~= "" and flag ~= "CRITICAL" and flag ~= "CRUSHING" and flag ~= "GLANCING" then text = _G[flag] @@ -330,22 +334,52 @@ local function Update(self, _, unit, event, flag, amount, school, texture) if text then local string = getString(element) + local flagAnimation = element.animationsByFlag[flag] + local xDirection, yDirection + + if flagAnimation then + xDirection, yDirection = flagAnimation[2], flagAnimation[3] + if flagAnimation[4] then + flagAnimation[2] = flagAnimation[2] * -1 + end + if flagAnimation[5] then + flagAnimation[3] = flagAnimation[3] * -1 + end + animation = flagAnimation[1] + else + xDirection, yDirection = animation[2], animation[3] + if animation[4] then + animation[2] = animation[2] * -1 + end + if animation[5] then + animation[3] = animation[3] * -1 + end + animation = animation[1] + end string.elapsed = 0 + string.point = fontData.point + string.relativeTo = fontData.relativeTo + string.fontX = fontData.x + string.fontY = fontData.y + string.scrollTime = fontData.scrollTime + string.fadeTime = fontData.scrollTime / 3 string.GetXY = element.animations[animation] string.radius = element.radius - string.xDirection = element.xDirection - string.yDirection = element.yDirection + string.xDirection = xDirection + string.yDirection = yDirection string.x = string.xDirection * element.xOffsetsByAnimation[animation] string.y = string.yDirection * element.yOffsetsByAnimation[animation] -- modified - if element.iconBounce then element.bounce = not element.bounce end + element.bounce[event] = not element.bounce[event] - string:SetFont(element.font, element.fontHeight * (element.multipliersByFlag[flag] or element.multipliersByFlag[""]), element.fontFlags) - string:SetFormattedText(element.iconBounce and (element.bounce and iconFormats[1] or iconFormats[2]) or element.format, text, texture or "") + string:SetFont(fontData.font, fontData.fontSize * (element.multipliersByFlag[flag] or element.multipliersByFlag[""]), fontData.fontFlags) + string:SetFormattedText(element.iconBounce[event] and (element.bounce[event] and element.iconFormats[event][1] or element.iconFormats[event][2]) + or element.formats[event] or "%1$s", text, texture or "") string:SetTextColor(color.r, color.g, color.b) - string:SetPoint("CENTER", element, "CENTER", string.x, string.y) + string:ClearAllPoints() + string:Point(fontData.point, element, fontData.relativeTo, fontData.x + string.x, fontData.y + string.y) string:SetAlpha(0) string:Show() @@ -354,14 +388,6 @@ local function Update(self, _, unit, event, flag, amount, school, texture) if not element:GetScript("OnUpdate") then element:SetScript("OnUpdate", onUpdate) end - - if element.alternateX then - element.xDirection = element.xDirection * -1 - end - - if element.alternateY then - element.yDirection = element.yDirection * -1 - end end end @@ -397,7 +423,7 @@ local function getEventFlag(resisted, blocked, absorbed, critical, glancing, cru or critical and "CRITICAL" or glancing and "GLANCING" or crushing and "CRUSHING" - or "" + or nil end -- modified @@ -411,20 +437,20 @@ local function prep(event, _, ...) event = auraType elseif event == "ENVIRONMENTAL_DAMAGE" then _, amount, _, school = ... - flag = getEventFlag(select(4, ...)) + flag = getEventFlag(select(4, ...)) or "NOFLAGWOUND" event = "WOUND" - elseif event == "RANGE_DAMAGE" or event == "SPELL_DAMAGE" or event == "SPELL_PERIODIC_DAMAGE" then + elseif event == "RANGE_DAMAGE" or event == "SPELL_DAMAGE" or event == "SPELL_PERIODIC_DAMAGE" then spellId, _, _, amount, _, school = ... - flag = getEventFlag(select(7, ...)) + flag = event == "SPELL_PERIODIC_DAMAGE" and "PERIODICWOUND" or getEventFlag(select(7, ...)) or "NOFLAGWOUND" texture = getTexture(spellId) event = "WOUND" elseif event == "SWING_DAMAGE" then amount, _, school = ... - flag = getEventFlag(select(4, ...)) + flag = getEventFlag(select(4, ...)) or "NOFLAGWOUND" event = "WOUND" elseif event == "SPELL_HEAL" or event == "SPELL_PERIODIC_HEAL" then spellId, _, school, amount = ... - flag = getEventFlag(nil, nil, select(6, ...)) + flag = event == "SPELL_PERIODIC_HEAL" and "PERIODICHEAL" or getEventFlag(nil, nil, select(6, ...)) or "NOFLAGHEAL" texture = getTexture(spellId) event = "HEAL" elseif event == "RANGE_MISSED" or event == "SPELL_MISSED" or event == "SPELL_PERIODIC_MISSED" then @@ -432,8 +458,8 @@ local function prep(event, _, ...) texture = getTexture(...) event = flag elseif event == "SWING_MISSED" then - flag = ... - event = flag + flag = "" + event = ... elseif event == "SPELL_INTERRUPT" then spellId, _, _, _, _, school = ... flag = "" @@ -584,33 +610,16 @@ local function Enable(self) element.EnableCLEU = EnableCLEU element.FeedbackToAnimate = {} - element.scrollTime = element.scrollTime or 1.2 - element.fadeTime = element.fadeTime or element.scrollTime / 3 - element.format = element.format or "%1$s" -- "%1$s |T%2$s:0:0:0:0:64:64:4:60:4:60|t" - - -- modified - iconFormats[1] = element.format == "%1$s |T%2$s:0:0:0:0:64:64:4:60:4:60|t" and "%1$s |T%2$s:0:0:0:0:64:64:4:60:4:60|t" or "|T%2$s:0:0:0:0:64:64:4:60:4:60|t %1$s" - iconFormats[2] = iconFormats[1] == "%1$s |T%2$s:0:0:0:0:64:64:4:60:4:60|t" and "|T%2$s:0:0:0:0:64:64:4:60:4:60|t %1$s" or "%1$s |T%2$s:0:0:0:0:64:64:4:60:4:60|t" + element.formats = {} + element.iconFormats = {} + element.bounce = {} + element.iconBounce = {} + element.fontData = {} element.radius = element.radius or 65 - element.xDirection = element.xDirection or 1 - element.yDirection = element.yDirection or 1 - - local font, _, fontFlags = element[1]:GetFont() - element.font = element.font or font or "Fonts\\FRIZQT__.TTF" - element.fontHeight = element.fontHeight or 18 - element.fontFlags = element.fontFlags or fontFlags or "" - - if element.alternateX == nil then - element.alternateX = true - end - - if element.alternateY == nil then - element.alternateY = false - end for i = 1, #element do - element[i]:SetFont(element.font, element.fontHeight, element.fontFlags) + element[i]:SetFont("Fonts\\FRIZQT__.TTF", 18, "") element[i]:Hide() end @@ -652,4 +661,4 @@ local function Disable(self) end end -oUF:AddElement("FloatingCombatFeedback", Path, Enable, Disable) +oUF:AddElement("FloatingCombatFeedback", Path, Enable, Disable) \ No newline at end of file diff --git a/Locales/deDE.lua b/Locales/deDE.lua index c291ab4..a30fe61 100644 --- a/Locales/deDE.lua +++ b/Locales/deDE.lua @@ -2,16 +2,16 @@ local E = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, Global local L = E.Libs.ACL:NewLocale("ElvUI", "deDE") L["Hits the 'Confirm' button automatically."] = "Klickt automatisch auf die 'Bestätigen'-Schaltfläche." -L["Picks up quest items and money automatically."] = "Sammelt Questgegenstände und Geld automatisch ein." -L["Fills 'DELETE' field automatically."] = "Füllt das 'LÖSCHEN'-Feld automatisch aus." -L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."] = "Wählt die erste Gesprächsoption aus, wenn sie die einzige verfügbare ist, es sei denn, eine Modifier-Taste wird gedrückt.\nVorsicht bei wichtigen Ereignisauslösern, es gibt keinen Sicherheitsmechanismus." +L["Picks up items and money automatically."] = "Hebt automatisch Gegenstände und Geld auf." +L["Automatically fills the 'DELETE' field."] = "Füllt das 'LÖSCHEN'-Feld automatisch aus." +L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."] = "Wählt die erste Gesprächsoption aus, wenn sie die einzige verfügbare ist, es sei denn, eine Modifier-Taste wird gedrückt.\nVorsicht bei wichtigen Ereignisauslösern, es gibt keinen Sicherheitsmechanismus." L["Accepts and turns in quests automatically while holding a modifier."] = "Nimmt Quests an und gibt sie automatisch ab, während eine Modifier-Taste gedrückt wird." L["Loot info wiped."] = "Beuteinformationen gelöscht." L["/lootinfo slash command to get a quick rundown of the recent lootings.\n\nUsage: /lootinfo Apple 60\n'Apple' - item/player name \n(search @self to get player loot)\n'60' - \ntime limit (<60 seconds ago), optional,\n/lootinfo !wipe - purge loot cache."] = "/lootinfo Befehl, um eine schnelle Übersicht über die kürzlichen Beutezüge zu erhalten.\n\nVerwendung: /lootinfo Apfel 60\n'Apfel' - Name des Items/Spielers \n(suche @self, um die Beute des Spielers zu erhalten)\n'60' - \nZeitlimit (<60 Sekunden), optional,\n/lootinfo !wipe - Beutekapazität leeren." -L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Färbt die Namen von Online-Freunden und Gildenmitgliedern in einigen Nachrichten und gestaltet die Würfe.\nBereits verarbeitete Chatblasen werden erst nach einem /reload neu gestaltet." +L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Färbt die Namen von Online-Freunden und Gildenmitgliedern in einigen Nachrichten und gestaltet die Würfe.\nBereits verarbeitete Chatblasen werden erst nach einem /reload neu gestaltet." L["Colors loot roll messages for you and other players."] = "Färbt Beutewürfelnachrichten für Sie und andere Spieler." L["Loot rolls icon size."] = "Größe der Beutewürfel-Symbole." -L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Gestaltet Beuteleisten neu.\nErfordert, dass 'Beutewurf' (Allgemein -> BlizzUI-Verbesserungen -> Beutewurf) aktiviert ist (das Umschalten dieses Moduls aktiviert es automatisch)." +L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Gestaltet Beuteleisten neu.\nErfordert, dass 'Beutewurf' (Allgemein -> BlizzUI-Verbesserungen -> Beutewurf) aktiviert ist (das Umschalten dieses Moduls aktiviert es automatisch)." L["Displays the name of the player pinging the minimap."] = "Zeigt den Namen des Spielers an, der die Minikarte anpingt." L["Displays the currently held currency amount next to the item prices."] = "Zeigt den aktuell gehaltenen Währungsbetrag neben den Gegenstandspreisen an." L["Narrows down the World(..Frame)."] = "Verkleinert das Welt(..Frame)." @@ -27,7 +27,7 @@ L["Adds shadows to all of the frames.\nDoes nothing unless you replace your ElvU L["Combat state notification alerts."] = "Kampfalarmmeldungen." L["Custom editbox position and size."] = "Benutzerdefinierte Position und Größe des Bearbeitungsfelds." L["Usage:".. - "\n/tnote list - returns all eixting notes".. + "\n/tnote list - returns all existing notes".. "\n/tnote wipe - clears all existing notes".. "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. "\n/tnote 1 get - same as set, returns existing notes".. @@ -68,28 +68,25 @@ L["Usage:".. "\n (1-percentage)*255, percentage*255)" L["Adds an icon next to chat hyperlinks."] = "Fügt neben Chat-Hyperlinks ein Symbol hinzu." L["A new action bar that collects usable quest items from your bag.\n\nDue to state actions limit, this module overrides bar10 created by ElvUI Extra Action Bars."] = "Eine neue Aktionsleiste, die verwendbare Questgegenstände aus deiner Tasche sammelt.\n\nAufgrund der Begrenzung der Zustandsaktionen überschreibt dieses Modul die von ElvUI Extra Action Bars erstellte Leiste 10." -L["Toggles the display of the actionbars backdrop."] = "Schaltet die Anzeige des Aktionsleisten-Hintergrunds um." -L["The frame won't show unless you mouse over it."] = "Der Rahmen wird nur angezeigt, wenn du mit der Maus darüber fährst." -L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Übernimmt das globale Verblassen. Maus darüber bewegen, Ziel auswählen, Fokus setzen, Gesundheit verlieren, Kampf beginnen wird die Transparenz entfernen. Andernfalls wird der Transparenzwert in den allgemeinen Aktionsleisteneinstellungen für globales Verblassen verwendet." +L["Toggles the display of the actionbar's backdrop."] = "Schaltet die Anzeige des Aktionsleisten-Hintergrunds um." +L["The frame will not be displayed unless hovered over."] = "Der Rahmen wird nur angezeigt, wenn du mit der Maus darüber fährst." +L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Übernimmt das globale Verblassen. Maus darüber bewegen, Ziel auswählen, Fokus setzen, Gesundheit verlieren, Kampf beginnen wird die Transparenz entfernen. Andernfalls wird der Transparenzwert in den allgemeinen Aktionsleisteneinstellungen für globales Verblassen verwendet." L["The first button anchors itself to this point on the bar."] = "Der erste Button verankert sich an diesem Punkt auf der Leiste." L["Right-click the item while holding the modifier to blacklist it. Blacklisted items will not show up on the bar.\nUse /questbarRestore to purge the blacklist."] = "Rechtsklicke auf den Gegenstand, während du den Modifikator hältst, um ihn auf die schwarze Liste zu setzen. Gegenstände auf der schwarzen Liste werden nicht auf der Leiste angezeigt.\nVerwende /questbarRestore, um die schwarze Liste zu löschen." -L["The amount of buttons to display."] = "Die Anzahl der anzuzeigenden Buttons." -L["The amount of buttons to display per row."] = "Die Anzahl der Buttons, die pro Reihe angezeigt werden sollen." +L["The number of buttons to display."] = "Die Anzahl der anzuzeigenden Buttons." +L["The number of buttons to display per row."] = "Die Anzahl der Buttons, die pro Reihe angezeigt werden sollen." L["The size of the action buttons."] = "Die Größe der Aktionsbuttons." -L["The spacing between buttons."] = "Der Abstand zwischen den Buttons." -L["The spacing between the backdrop and the buttons."] = "Der Abstand zwischen dem Hintergrund und den Buttons." -L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."] = "Multipliziere die Höhe oder Breite des Hintergrunds mit diesem Wert. Dies ist nützlich, wenn du mehr als eine Leiste hinter einem Hintergrund haben möchtest." -L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"] = "Dies funktioniert wie ein Makro. Du kannst verschiedene Situationen ausführen, um die Aktionsleiste unterschiedlich ein-/auszublenden.\n Beispiel: '[combat] showhide'" -L["Adds anchoring options to movers' nudges."] = "Fügt Verankerungsoptionen zu den Verschiebungen der Mover hinzu." -L["Mod-clicking an item suggest a skill/item to process it."] = "Mod-Klick auf einen Gegenstand schlägt eine Fertigkeit/einen Gegenstand zur Verarbeitung vor." -L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = +L["Spacing between the buttons."] = "Der Abstand zwischen den Buttons." +L["Spacing between the backdrop and the buttons."] = "Der Abstand zwischen dem Hintergrund und den Buttons." +L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."] = "Multipliziere die Höhe oder Breite des Hintergrunds mit diesem Wert. Dies ist nützlich, wenn du mehr als eine Leiste hinter einem Hintergrund haben möchtest." +L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"] = "Dies funktioniert wie ein Makro. Du kannst verschiedene Situationen ausführen, um die Aktionsleiste unterschiedlich ein-/auszublenden.\n Beispiel: '[combat] showhide'" +L["Adds anchoring options to the movers' nudges."] = "Fügt Verankerungsoptionen zu den Verschiebungen der Mover hinzu." +L["Mod-clicking an item suggests a skill/item to process it."] = "Mod-Klick auf einen Gegenstand schlägt eine Fertigkeit/einen Gegenstand zur Verarbeitung vor." +L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = "Halten Sie %s gedrückt, während Sie mit der linken Maustaste auf einen Stapel klicken, um ihn in zwei Teile zu teilen; um verfügbare Kopien zu kombinieren, klicken Sie stattdessen mit der rechten Maustaste.\n\nModifiziert auch den SplitStackFrame, um ein Eingabefeld anstelle von Pfeilen zu verwenden." L["Extends the bags functionality."] = "Erweitert die Funktionalität der Taschen." -L["Handles automated repositioning of the newly received items."] = "Handhabt die automatische Neupositionierung der neu erhaltenen Gegenstände." -L["Default method: type > inventoryslotid > ilvl > name."] = "Standardmethode: Typ > Inventarplatz-ID > Gegenstandsstufe > Name." +L["Default method: type > inventory slot ID > item level > name."] = "Standardmethode: Typ > Inventarplatz-ID > Gegenstandsstufe > Name." L["Listed ItemIDs will not get sorted."] = "Aufgelistete Gegenstands-IDs werden nicht sortiert." -L["Double-click the title text to minimize the section."] = "Doppelklicken Sie auf den Titeltext, um den Abschnitt zu minimieren." -L["Minimized section's line color."] = "Linienfarbe des minimierten Abschnitts." L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"] = "Z.B. Interface\\Icons\\INV_Misc_QuestionMark" L["Invalid condition format: "] = "Ungültiges Bedingungsformat: " L["The generated custom sorting method did not return a function."] = "Generierte benutzerdefinierte Sortiermethode hat keine Funktion zurückgegeben." @@ -97,26 +94,26 @@ L["The loaded custom sorting method did not return a function."] = "Geladene ben L["Item received: "] = "Gegenstand erhalten: " L[" added."] = " hinzugefügt." L[" removed."] = " entfernt." -L["Handles automated repositioning of the newly received items.".. +L["Handles the automated repositioning of the newly received items.".. "\nSyntax: filter@value\n\n".. "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches InventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. "Look up GetItemInfo API for more info on filters. ".. "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. "Example usage (priest t8 or Shadowmourne):\n".. "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. + "The below one notifies of the newly acquired items.\n\n".. "local icon = GetContainerItemInfo(bagID, slotID)\n".. "local _, link = GetItemInfo(itemID)\n".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. @@ -125,16 +122,16 @@ L["Handles automated repositioning of the newly received items.".. "Verarbeitet die automatische Neupositionierung von neu erhaltenen Gegenständen.".. "\nSyntax: filter@wert\n\n".. "Verfügbare Filter:\n".. - "id@zahl - entspricht der GegenstandsID,\n".. - "name@string - entspricht dem Namen,\n".. - "subtype@string - entspricht dem Untertyp,\n".. - "ilvl@zahl - entspricht dem Gegenstandslevel,\n".. - "uselevel@zahl - entspricht dem Ausrüstungslevel,\n".. - "quality@zahl - entspricht der Qualität,\n".. - "equipslot@zahl - entspricht der InventarPlatzID,\n".. - "maxstack@zahl - entspricht dem Stapellimit,\n".. - "price@zahl - entspricht dem Verkaufspreis,\n\n".. - "tooltip@string - entspricht dem Tooltip-Text,\n\n".. + " id@zahl - entspricht der GegenstandsID,\n".. + " name@string - entspricht dem Namen,\n".. + " subtype@string - entspricht dem Untertyp,\n".. + " ilvl@zahl - entspricht dem Gegenstandslevel,\n".. + " uselevel@zahl - entspricht dem Ausrüstungslevel,\n".. + " quality@zahl - entspricht der Qualität,\n".. + " equipslot@zahl - entspricht der InventarPlatzID,\n".. + " maxstack@zahl - entspricht dem Stapellimit,\n".. + " price@zahl - entspricht dem Verkaufspreis,\n\n".. + " tooltip@string - entspricht dem Tooltip-Text,\n\n".. "Alle String-Übereinstimmungen sind nicht case-sensitive und entsprechen nur den alphanumerischen Symbolen. Standard-Lua-Logik wird angewendet. ".. "Siehe GetItemInfo API für weitere Informationen zu Filtern. ".. "Verwenden Sie GetAuctionItemClasses und GetAuctionItemSubClasses (wie im AH), um die lokalisierten Werte für Typen und Untertypen zu erhalten.\n\n".. @@ -147,6 +144,47 @@ L["Handles automated repositioning of the newly received items.".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. "print('Gegenstand erhalten: ' .. string)" +L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Syntax: filter@wert\n\n".. + "Verfügbare Filter:\n".. + " id@nummer - stimmt mit ItemID überein,\n".. + " name@text - stimmt mit Namen überein,\n".. + " type@text - stimmt mit Typ überein,\n".. + " subtype@text - stimmt mit Subtyp überein,\n".. + " ilvl@nummer - stimmt mit Gegenstandsstufe überein,\n".. + " uselevel@nummer - stimmt mit Ausrüstungsstufe überein,\n".. + " quality@nummer - stimmt mit Qualität überein,\n".. + " equipslot@nummer - stimmt mit InventarPlatzID überein,\n".. + " maxstack@nummer - stimmt mit Stapellimit überein,\n".. + " price@nummer - stimmt mit Verkaufspreis überein,\n".. + " tooltip@text - stimmt mit Tooltip-Text überein.\n\n".. + "Alle Textübereinstimmungen sind nicht von der Groß-/Kleinschreibung abhängig und stimmen nur mit alphanumerischen Symbolen überein.\n".. + "Standard-Lua-Logik für Verzweigungen (und/oder/Klammern/usw.) wird angewendet.\n\n".. + "Beispiel (Priester t8 oder Schattengram):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["Available Item Types"] = "Verfügbare Gegenstandstypen" +L["Lists all available item subtypes for each available item type."] = + "Listet alle verfügbaren Gegenstandssubtypen für jeden verfügbaren Gegenstandstyp auf." +L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."] = + "Hält man diese Taste beim Interagieren mit einem Händler gedrückt, werden alle Artikel gekauft, die die Auto-Kauf-Einstellungen erfüllen.\n".. + "Mit einem Mod-Klick auf den Eintrag in der Kaufliste wird nur ein Artikel gekauft, unabhängig von der '@menge'-Regel." L["Default method: type > inventoryslotid > ilvl > name.\n\n".. "Accepts custom functions (bagID and slotID are available at the a/b.bagID/slotID).\n\n".. "function(a,b)\n".. @@ -170,7 +208,7 @@ L["Syntax:".. "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -180,13 +218,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. @@ -209,13 +247,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(Spieler hat eine Aura gewonnen/verloren)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5=UnitName('player')]".. + "\n[5=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Schlechter Zauber')".. "\nthen print(UnitName('party'..i)..' ist betroffen!')".. @@ -223,7 +261,7 @@ L["Syntax:".. "\n\nDieses Modul analysiert Zeichenketten, also versuchen Sie, Ihren Code streng an die Syntax zu halten, sonst funktioniert er möglicherweise nicht." L["Highlights auras."] = "Hebt Auren hervor." L["E.g. 42292"] = "Z.B. 42292" -L["Aplies highlights to all auras passing the selected filter."] = "Hervorhebungen für alle Auren, die den ausgewählten Filter passieren." +L["Applies highlights to all auras passing the selected filter."] = "Hervorhebungen für alle Auren, die den ausgewählten Filter passieren." L["Priority: spell, filter, curable/stealable."] = "Priorität: Zauber, Filter, heilbar/stehlbar." L["If toggled, the GLOBAL Spell or Filter entry values would be used."] = "Wenn aktiviert, werden die globalen Zauber- oder Filterwerte verwendet." L["Makes auras grow sideswise."] = "Lässt Auren seitlich wachsen." @@ -235,7 +273,15 @@ L["Right-click a player buff to cancel it."] = "Klicken Sie mit der rechten Maus L["Disables debuffs desaturation."] = "Deaktiviert die Desättigung von Debuffs." L["Saturated Debuffs"] = "Gesättigte Debuffs" L["Confirm Rolls"] = "Würfe bestätigen" -L["Quest Items and Money"] = "Questitems und Geld" +L["Auto Pickup"] = "Automatisches Aufheben" +L["Swift Buy"] = "Schneller Kauf" +L["Buys out items automatically."] = "Kauft Artikel automatisch auf." +L["Failsafe"] = "Ausfallsicherung" +L["Enables popup confirmation dialog."] = "Aktiviert Popup-Bestätigungsdialog." +L["Add Set"] = "Set hinzufügen" +L["Delete Set"] = "Set löschen" +L["Select Set"] = "Set auswählen" +L["Auto Buy"] = "Automatischer Kauf" L["Fill Delete"] = "Löschen ausfüllen" L["Gossip"] = "Gespräch" L["Accept Quest"] = "Quest annehmen" @@ -271,7 +317,6 @@ L["Select Container Type"] = "Behältertyp auswählen" L["Settings"] = "Einstellungen" L["Add Section"] = "Abschnitt hinzufügen" L["Delete Section"] = "Abschnitt löschen" -L["Section Length"] = "Abschnittslänge" L["Select Section"] = "Abschnitt auswählen" L["Section Priority"] = "Abschnittspriorität" L["Section Spacing"] = "Abschnittsabstand" @@ -279,8 +324,6 @@ L["Collection Method"] = "Sammelmethode" L["Sorting Method"] = "Sortiermethode" L["Ignore Item (by ID)"] = "Item ignorieren (nach ID)" L["Remove Ignored"] = "Ignorierte entfernen" -L["Minimize"] = "Minimieren" -L["Line Color"] = "Linienfarbe" L["Title"] = "Titel" L["Color"] = "Farbe" L["Attach to Icon"] = "An Symbol anheften" @@ -443,13 +486,10 @@ L["Add Texture Path"] = "Texturpfad hinzufügen" L["Remove Selected Texture"] = "Ausgewählte Textur entfernen" L["Titles"] = "Titel" L["Reaction Color"] = "Reaktionsfarbe" -L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"] = - "Halten Sie dies gedrückt, während Sie den Befehl /addOccupation verwenden, um die Liste des aktuellen Ziel-/Mauszeiger-Berufs zu löschen.\nVergessen Sie nicht, die Modifikator+Taste-Bindung aufzuheben!" L["Color based on reaction type."] = "Farbe basierend auf Reaktionstyp." L["Nameplates"] = "Namensplaketten" L["Unitframes"] = "Einheitenrahmen" -L["An icon similar to the minimap search.\n\nTooltip scanning, might not be precise.\n\nFor consistency reasons, no keywards are added by defult, use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."] = - "Ein Symbol ähnlich der Minikartensuche.\n\nTooltip-Scannen, könnte ungenau sein.\n\nAus Gründen der Konsistenz werden standardmäßig keine Schlüsselwörter hinzugefügt, verwenden Sie den Befehl /addOccupation, um die entsprechenden selbst zu markieren (muss nur einmal pro eindeutigem Berufstext gemacht werden)." +L["An icon similar to the minimap search."] = "Ein Symbol ähnlich der Minikartensuche." L["Displays player guild text."] = "Zeigt den Gildentext des Spielers an." L["Displays NPC occupation text."] = "Zeigt den Berufstext des NPC an." L["Strata"] = "Schicht" @@ -472,40 +512,6 @@ L["Unmark all plates."] = "Entmarkiert alle Plaketten." L["Usage: '/qmark' macro bound to a key of your choice.\n\nDon't forget to also unbind your modifier keybinds!"] = "Verwendung: '/qmark' Makro auf eine Taste Ihrer Wahl gebunden.\n\nVergessen Sie nicht, auch Ihre Modifikatortasten zu entbinden!" L["Use Backdrop"] = "Hintergrund verwenden" -L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."] = - "Verwendung:\n%%d=%%s\n\n%%d - Index aus der Liste unten\n%%s - Schlüsselwörter zum Suchen\n\nIndizes der Symbole:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAuch verfügbar als '/addOccupation %%d' Befehl, wobei %%d ein optionaler Symbolindex ist.".. - "Wenn kein Index angegeben ist, durchläuft dieser Befehl alle verfügbaren Symbole. Funktioniert entweder auf ZIEL oder MOUSEOVER, wobei MOUSEOVER priorisiert wird." L["Linked Style Filter Triggers"] = "Verknüpfte Stilfilterauslöser" L["Select Link"] = "Verknüpfung auswählen" L["New Link"] = "Neue Verknüpfung" @@ -610,7 +616,7 @@ L["Disable Event"] = "Ereignis deaktivieren" L["School"] = "Schule" L["Use School Colors"] = "Schulfarben verwenden" L["Colors"] = "Farben" -L["Colors (School)"] = "Farben (Schule)" +L["Color (School)"] = "Farbe (Schule)" L["Animation Type"] = "Animationstyp" L["Custom Animation"] = "Benutzerdefinierte Animation" L["Flag Settings"] = "Flaggeneinstellungen" @@ -696,7 +702,7 @@ L["Rare Elite"] = "Seltene Elite" L["Class Spec Icons"] = "Klassenspezialisierungssymbole" L["Classification Textures"] = "Klassifizierungstexturen" L["Use Nameplates' Icons"] = "Namensplaketten-Symbole verwenden" -L["Color enemy npc icon based on the unit type."] = "Gegnerisches NPC-Symbol basierend auf dem Einheitentyp einfärben." +L["Color enemy NPC icon based on the unit type."] = "Gegnerisches NPC-Symbol basierend auf dem Einheitentyp einfärben." L["Strata and Level"] = "Ebene und Stufe" L["Warrior"] = "Krieger" L["Warlock"] = "Hexenmeister" @@ -768,7 +774,6 @@ L["On meeting multiple conditions, colors from the tab with the highest priority L["Copy Tab"] = "Tab kopieren" L["Select a tab to copy its settings onto the current tab."] = "Wählen Sie einen Tab aus, um dessen Einstellungen auf den aktuellen Tab zu kopieren." L["Flash"] = "Blinken" -L["Toggle color flash for the current tab."] = "Farbiges Blinken für den aktuellen Tab umschalten." L["Speed"] = "Geschwindigkeit" L["Glow"] = "Leuchten" L["Determines which glow to apply when statusbars are not detached from frame."] = "Bestimmt, welches Leuchten angewendet wird, wenn Statusleisten nicht vom Rahmen getrennt sind." @@ -785,7 +790,7 @@ L["Disabled unless classbar is enabled."] = "Deaktiviert, es sei denn, die Klass L["InfoPanel Color"] = "Infopanel-Farbe" L["Disabled unless infopanel is enabled."] = "Deaktiviert, es sei denn, das Infopanel ist aktiviert." L["ClassBar Adapt To"] = "Klassenleiste anpassen an" -L["Copies color of the selected bar."] = "Kopiert die Farbe der ausgewählten Leiste." +L["Copies the color of the selected bar."] = "Kopiert die Farbe der ausgewählten Leiste." L["InfoPanel Adapt To"] = "Infopanel anpassen an" L["Override Mode"] = "Überschreibungsmodus" L["'None' - threat borders highlight will be prioritized over this one".. @@ -803,38 +808,49 @@ L["Handle only player combat log events."] = "Nur Kampfprotokoll-Ereignisse des L["Rotate Icon"] = "Symbol drehen" L["Usage example:".. "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/5]@@ - gibt true/false zurück, basierend darauf, ob der betreffende Tab (im obigen Beispiel: 'player' - Zieleinheit; 'Power' - Ziel-Statusleiste; '3' - Ziel-Tab) aktiv ist oder nicht (Erwähnung derselben Einheit/Gruppe ist deaktiviert; nicht rekursiv)".. - "\n(>/>=/<=/5]@@ - gibt true/false zurück, basierend darauf, ob der betreffende Tab ".. + "(im obigen Beispiel: 'player' - Zieleinheit; 'Power' - Ziel-Statusleiste; '3' - Ziel-Tab) aktiv ist oder nicht".. + "\n(>/>=/<=/=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = + "Verarbeitet die automatische Positionierung von Gegenständen.\n".. + "Syntax: filter@value\n\n".. + "Verfügbare Filter:\n".. + " id@number - entspricht itemID,\n".. + " name@string - entspricht Name,\n".. + " type@string - entspricht Typ,\n".. + " subtype@string - entspricht Untertyp,\n".. + " ilvl@number - entspricht ilvl,\n".. + " uselevel@number - entspricht Ausrüstungsstufe,\n".. + " quality@number - entspricht Qualität,\n".. + " equipslot@number - entspricht InventorySlotID,\n".. + " maxstack@number - entspricht Stapelgrenze,\n".. + " price@number - entspricht Verkaufspreis,\n".. + " tooltip@string - entspricht Tooltip-Text,\n".. + " set@setName - entspricht Ausrüstungsset-Gegenständen.\n\n".. + "Alle Stringübereinstimmungen sind nicht groß-/kleinschreibungsempfindlich und entsprechen nur den alphanumerischen Symbolen.\n".. + "Standard Lua-Logik für Verzweigungen (und/oder/Elternklammern/usw.) gilt.\n\n".. + "Beispielverwendung (Priester t8 oder Shadowmourne):\n".. + "(quality@4 und ilvl@>=219 und ilvl@<=245 und subtype@cloth und name@ofSanctification) oder name@shadowmourne.\n\n".. + "Akzeptiert benutzerdefinierte Funktionen (bagID, slotID, itemID sind verfügbar)\n".. + "Der folgende benachrichtigt über die neu erworbenen Gegenstände.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Gegenstand erhalten: ' .. string)" +L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Syntax: filter@value@amount\n\n".. + "Verfügbare Filter:\n".. + " id@number@amount(+)/+ - entspricht itemID,\n".. + " name@string@amount(+)/+ - entspricht Name,\n".. + " type@string@amount(+)/+ - entspricht Typ,\n".. + " subtype@string@amount(+)/+ - entspricht Untertyp,\n".. + " ilvl@number@amount(+)/+ - entspricht ilvl,\n".. + " uselevel@number@amount(+)/+ - entspricht Ausrüstungsstufe,\n".. + " quality@number@amount(+)/+ - entspricht Qualität,\n".. + " equipslot@number@amount(+)/+ - entspricht InventorySlotID,\n".. + " maxstack@number@amount(+)/+ - entspricht Stapelgrenze,\n".. + " price@number@amount(+)/+ - entspricht Verkaufspreis,\n".. + " tooltip@string@amount(+)/+ - entspricht Tooltip-Text.\n\n".. + "Der optionale 'amount'-Teil könnte sein:\n".. + " eine Zahl - um eine feste Menge zu kaufen,\n".. + " ein + Zeichen - um den bestehenden Teilstapel aufzufüllen oder einen neuen zu kaufen,\n".. + " beides (z.B. 5+) - um genug Gegenstände zu kaufen, um eine bestimmte Gesamtmenge zu erreichen (in diesem Fall 5),\n".. + " weggelassen - standardmäßig 1.\n\n".. + "Alle Stringübereinstimmungen sind nicht groß-/kleinschreibungsempfindlich und entsprechen nur den alphanumerischen Symbolen.\n".. + "Standard Lua-Logik für Verzweigungen (und/oder/Elternklammern/usw.) gilt.\n\n".. + "Beispielverwendung (Priester t8 oder Shadowmourne):\n".. + "(quality@4 und ilvl@>=219 und ilvl@<=245 und subtype@cloth und name@ofSanctification) oder name@shadowmourne." +L["PERIODIC"] = "PERIODISCH" +L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."] = "Halten Sie diese Taste gedrückt, während Sie den Befehl /addOccupation verwenden, um die Liste des aktuellen Ziels/Mauszeiger-NPC zu löschen." +L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."] = "Verwenden Sie den Befehl /addOccupation, während Sie auf ein NPC zielen/überfahren, um es zur Liste hinzuzufügen. Verwenden Sie ihn erneut, um zu wechseln." +L["Style Filter Icons"] = "Stilfilter-Symbole" +L["Custom icons for the style filter."] = "Benutzerdefinierte Symbole für den Stilfilter." +L["Whitelist"] = "Whitelist" +L["X Direction"] = "X-Richtung" +L["Y Direction"] = "Y-Richtung" +L["Create Icon"] = "Icon erstellen" +L["Delete Icon"] = "Icon löschen" +L["0 to match frame width."] = "0 um die Rahmenbreite anzupassen." +L["Remove a NPC"] = "Einen NPC entfernen" +L["Change a NPC's Occupation"] = "Beruf eines NPC ändern" +L["...to the currently selected one."] = "...zum aktuell ausgewählten." +L["Select Occupation"] = "Beruf auswählen" \ No newline at end of file diff --git a/Locales/enUS.lua b/Locales/enUS.lua index 7ca29f0..373cc45 100644 --- a/Locales/enUS.lua +++ b/Locales/enUS.lua @@ -2,22 +2,22 @@ local E = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, Global local L = E.Libs.ACL:NewLocale("ElvUI", "enUS", true) L["Hits the 'Confirm' button automatically."] = true -L["Picks up quest items and money automatically."] = true -L["Fills 'DELETE' field automatically."] = true -L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."] = true +L["Picks up items and money automatically."] = true +L["Automatically fills the 'DELETE' field."] = true +L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."] = true L["Accepts and turns in quests automatically while holding a modifier."] = true L["Loot info wiped."] = true L["/lootinfo slash command to get a quick rundown of the recent lootings."] = true -L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = true +L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = true L["Colors loot roll messages for you and other players."] = true L["Loot rolls icon size."] = true -L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = true +L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = true L["Displays the name of the player pinging the minimap."] = true L["Displays the currently held currency amount next to the item prices."] = true L["Narrows down the World(..Frame)."] = true L["'Out of mana', 'Ability is not ready yet', etc."] = true L["Re-enable quest updates."] = true -L["Unless holding a modifier, hovering units, items, and spells draws no tooltip.\nModifies cursor tooltips only."] = true +L["Tooltips will not display when hovering over units, items, and spells unless a modifier is held.\nModifies cursor tooltips only."] = true L["255, 210, 0 - Blizzard's yellow."] = true L["Text to display upon entering combat."] = true L["Text to display upon leaving combat."] = true @@ -28,12 +28,12 @@ L["Adds shadows to all of the frames.\nDoes nothing unless you replace your ElvU L["Combat state notification alerts."] = true L["Custom editbox position and size."] = true L["Usage:".. - "\n/tnote list - returns all eixting notes".. + "\n/tnote list - returns all existing notes".. "\n/tnote wipe - clears all existing notes".. "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. "\n/tnote 1 get - same as set, returns existing notes".. "\n/tnote 1 set YourNoteHere - adds a note to the designated index from the list ".. - "or to a currently shown tooltip text if the second argument (1 in this case) is ommitted, ".. + "or to a currently shown tooltip text if the second argument (1 in this case) is omitted, ".. "supports functions and coloring ".. "(providing no text clears the note);".. "\nto break the lines, use ::".. @@ -48,27 +48,24 @@ L["Usage:".. "\n ..UnitHealth('mouseover'), ".. "\n (1-percentage)*255, percentage*255)"] = true L["Adds an icon next to chat hyperlinks."] = true -L["Toggles the display of the actionbars backdrop."] = true -L["The frame won't show unless you mouse over it."] = true -L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = true +L["Toggles the display of the actionbar's backdrop."] = true +L["The frame will not be displayed unless hovered over."] = true +L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = true L["The first button anchors itself to this point on the bar."] = true L["Right-click the item while holding the modifier to blacklist it. Blacklisted items will not show up on the bar.\nUse /questbarRestore to purge the blacklist."] = true -L["The amount of buttons to display."] = true -L["The amount of buttons to display per row."] = true +L["The number of buttons to display."] = true +L["The number of buttons to display per row."] = true L["The size of the action buttons."] = true -L["The spacing between buttons."] = true -L["The spacing between the backdrop and the buttons."] = true -L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."] = true -L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"] = true -L["Adds anchoring options to movers' nudges."] = true -L["Mod-clicking an item suggest a skill/item to process it."] = true -L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = true +L["Spacing between the buttons."] = true +L["Spacing between the backdrop and the buttons."] = true +L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."] = true +L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"] = true +L["Adds anchoring options to the movers' nudges."] = true +L["Mod-clicking an item suggests a skill/item to process it."] = true +L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = true L["Extends the bags functionality."] = true -L["Handles automated repositioning of the newly received items."] = true -L["Default method: type > inventoryslotid > ilvl > name."] = true +L["Default method: type > inventory slot ID > item level > name."] = true L["Listed ItemIDs will not get sorted."] = true -L["Double-click the title text to minimize the section."] = true -L["Minimized section's line color."] = true L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"] = true L["Invalid condition format: "] = true L["The generated custom sorting method did not return a function."] = true @@ -76,31 +73,52 @@ L["The loaded custom sorting method did not return a function."] = true L["Item received: "] = true L[" added."] = true L[" removed."] = true -L["Handles automated repositioning of the newly received items.".. +L["Handles the automated repositioning of the newly received items.".. "\nSyntax: filter@value\n\n".. "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches InventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. "Look up GetItemInfo API for more info on filters. ".. "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. "Example usage (priest t8 or Shadowmourne):\n".. "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. + "The below one notifies of the newly acquired items.\n\n".. "local icon = GetContainerItemInfo(bagID, slotID)\n".. "local _, link = GetItemInfo(itemID)\n".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. "print('Item received: ' .. string)"] = true +L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = true +L["Available Item Types"] = true +L["Lists all available item subtypes for each available item type."] = true +L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."] = true L["Default method: type > inventoryslotid > ilvl > name.\n\n".. "Accepts custom functions (bagID and slotID are available at the a/b.bagID/slotID).\n\n".. "function(a,b)\n".. @@ -118,7 +136,7 @@ L["Syntax:".. "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -128,13 +146,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. @@ -142,7 +160,7 @@ L["Syntax:".. "\n\nThis module parses strings, so try to have your code follow the syntax strictly, or else it might not work."] = true L["Highlights auras."] = true L["E.g. 42292"] = true -L["Aplies highlights to all auras passing the selected filter."] = true +L["Applies highlights to all auras passing the selected filter."] = true L["Priority: spell, filter, curable/stealable."] = true L["If toggled, the GLOBAL Spell or Filter entry values would be used."] = true L["Makes auras grow sideswise."] = true @@ -150,7 +168,15 @@ L["Turns off texture fill."] = true L["Makes auras flicker right before fading out."] = true L["Disables border coloring."] = true L["Confirm Rolls"] = true -L["Quest Items and Money"] = true +L["Auto Pickup"] = true +L["Swift Buy"] = true +L["Buys out items automatically."] = true +L["Failsafe"] = true +L["Enables popup confirmation dialog."] = true +L["Add Set"] = true +L["Delete Set"] = true +L["Select Set"] = true +L["Auto Buy"] = true L["Fill Delete"] = true L["Gossip"] = true L["Accept Quest"] = true @@ -186,7 +212,6 @@ L["Select Container Type"] = true L["Settings"] = true L["Add Section"] = true L["Delete Section"] = true -L["Section Length"] = true L["Select Section"] = true L["Section Priority"] = true L["Section Spacing"] = true @@ -194,8 +219,6 @@ L["Collection Method"] = true L["Sorting Method"] = true L["Ignore Item (by ID)"] = true L["Remove Ignored"] = true -L["Minimize"] = true -L["Line Color"] = true L["Title"] = true L["Color"] = true L["Attach to Icon"] = true @@ -351,11 +374,10 @@ L["Add Texture Path"] = true L["Remove Selected Texture"] = true L["Titles"] = true L["Reaction Color"] = true -L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"] = true L["Color based on reaction type."] = true L["Nameplates"] = true L["Unitframes"] = true -L["An icon similar to the minimap search.\n\nTooltip scanning, might not be precise.\n\nFor consistency reasons, no keywards are added by defult, use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."] = true +L["An icon similar to the minimap search."] = true L["Displays player guild text."] = true L["Displays NPC occupation text."] = true L["Strata"] = true @@ -377,23 +399,6 @@ L["Unmark All"] = true L["Unmark all plates."] = true L["Usage: '/qmark' macro bound to a key of your choice.\n\nDon't forget to also unbind your modifier keybinds!"] = true L["Use Backdrop"] = true -L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."] = true L["Linked Style Filter Triggers"] = true L["Select Link"] = true L["New Link"] = true @@ -508,7 +513,7 @@ L["Disable Event"] = true L["School"] = true L["Use School Colors"] = true L["Colors"] = true -L["Colors (School)"] = true +L["Color (School)"] = true L["Animation Type"] = true L["Custom Animation"] = true L["Flag Settings"] = true @@ -590,7 +595,7 @@ L["Rare Elite"] = true L["Class Spec Icons"] = true L["Classification Textures"] = true L["Use Nameplates' Icons"] = true -L["Color enemy npc icon based on the unit type."] = true +L["Color enemy NPC icon based on the unit type."] = true L["Strata and Level"] = true L["Warrior"] = true L["Warlock"] = true @@ -662,7 +667,6 @@ L["On meeting multiple conditions, colors from the tab with the highest priority L["Copy Tab"] = true L["Select a tab to copy its settings onto the current tab."] = true L["Flash"] = true -L["Toggle color flash for the current tab."] = true L["Speed"] = true L["Glow"] = true L["Determines which glow to apply when statusbars are not detached from frame."] = true @@ -679,7 +683,7 @@ L["Disabled unless classbar is enabled."] = true L["InfoPanel Color"] = true L["Disabled unless infopanel is enabled."] = true L["ClassBar Adapt To"] = true -L["Copies color of the selected bar."] = true +L["Copies the color of the selected bar."] = true L["InfoPanel Adapt To"] = true L["Override Mode"] = true L["'None' - threat borders highlight will be prioritized over this one".. "\n'Threat' - this highlight will be prioritized."] = true @@ -694,17 +698,22 @@ L["Handle only player combat log events."] = true L["Rotate Icon"] = true L["Usage example:".. "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = true +L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = true +L["PERIODIC"] = true +L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."] = true +L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."] = true +L["Style Filter Icons"] = true +L["Custom icons for the style filter."] = true +L["Whitelist"] = true +L["X Direction"] = true +L["Y Direction"] = true +L["Create Icon"] = true +L["Delete Icon"] = true +L["0 to match frame width."] = true +L["Remove a NPC"] = true +L["Change a NPC's Occupation"] = true +L["...to the currently selected one."] = true +L["Select Occupation"] = true \ No newline at end of file diff --git a/Locales/esMX.lua b/Locales/esMX.lua index 4878aeb..e763cb3 100644 --- a/Locales/esMX.lua +++ b/Locales/esMX.lua @@ -2,16 +2,16 @@ local E = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, Global local L = E.Libs.ACL:NewLocale("ElvUI", "esMX") L["Hits the 'Confirm' button automatically."] = "Presiona el botón 'Confirmar' automáticamente." -L["Picks up quest items and money automatically."] = "Recoge automáticamente los objetos de misión y el dinero." -L["Fills 'DELETE' field automatically."] = "Rellena el campo 'BORRAR' automáticamente." -L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."] = "Selecciona la primera opción de diálogo si es la única disponible a menos que se mantenga presionado un modificador.\nCuidado con los desencadenantes de eventos importantes, no hay un mecanismo a prueba de fallos." +L["Picks up items and money automatically."] = "Recoge objetos y dinero automáticamente." +L["Automatically fills the 'DELETE' field."] = "Rellena el campo 'BORRAR' automáticamente." +L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."] = "Selecciona la primera opción de diálogo si es la única disponible a menos que se mantenga presionado un modificador.\nCuidado con los desencadenantes de eventos importantes, no hay un mecanismo a prueba de fallos." L["Accepts and turns in quests automatically while holding a modifier."] = "Acepta y entrega misiones automáticamente mientras se mantiene presionado un modificador." L["Loot info wiped."] = "Información de botín borrada." L["/lootinfo slash command to get a quick rundown of the recent lootings.\n\nUsage: /lootinfo Apple 60\n'Apple' - item/player name \n(search @self to get player loot)\n'60' - \ntime limit (<60 seconds ago), optional,\n/lootinfo !wipe - purge loot cache."] = "Comando /lootinfo para obtener un resumen rápido de los saqueos recientes.\n\nUso: /lootinfo Manzana 60\n'Manzana' - nombre del objeto/jugador \n(buscar @self para obtener el botín del jugador)\n'60' - \nlímite de tiempo (<60 segundos), opcional,\n/lootinfo !wipe - purgar el caché de botín." -L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Colorea los nombres de amigos en línea y compañeros de hermandad en algunos mensajes y estiliza las tiradas.\nLas burbujas de chat ya manejadas no se estilizarán hasta que hagas /reload." +L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Colorea los nombres de amigos en línea y compañeros de hermandad en algunos mensajes y estiliza las tiradas.\nLas burbujas de chat ya manejadas no se estilizarán hasta que hagas /reload." L["Colors loot roll messages for you and other players."] = "Colorea los mensajes de tiradas de botín para ti y otros jugadores." L["Loot rolls icon size."] = "Tamaño del icono de tiradas de botín." -L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Rediseña las barras de botín.\nRequiere que 'Tirada de botín' (General -> Mejoras de BlizzUI -> Tirada de botín) esté habilitado (activar este módulo lo habilita automáticamente)." +L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Rediseña las barras de botín.\nRequiere que 'Tirada de botín' (General -> Mejoras de BlizzUI -> Tirada de botín) esté habilitado (activar este módulo lo habilita automáticamente)." L["Displays the name of the player pinging the minimap."] = "Muestra el nombre del jugador que marca el minimapa." L["Displays the currently held currency amount next to the item prices."] = "Muestra la cantidad de moneda actualmente poseída junto a los precios de los objetos." L["Narrows down the World(..Frame)."] = "Reduce el World(..Frame)." @@ -27,7 +27,7 @@ L["Adds shadows to all of the frames.\nDoes nothing unless you replace your ElvU L["Combat state notification alerts."] = "Alertas de notificación de estado de combate." L["Custom editbox position and size."] = "Posición y tamaño personalizados del cuadro de edición." L["Usage:".. - "\n/tnote list - returns all eixting notes".. + "\n/tnote list - returns all existing notes".. "\n/tnote wipe - clears all existing notes".. "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. "\n/tnote 1 get - same as set, returns existing notes".. @@ -68,29 +68,26 @@ L["Usage:".. "\n (1-percentage)*255, percentage*255)" L["Adds an icon next to chat hyperlinks."] = "Añade un icono junto a los hipervínculos del chat." L["A new action bar that collects usable quest items from your bag.\n\nDue to state actions limit, this module overrides bar10 created by ElvUI Extra Action Bars."] = "Una nueva barra de acción que recolecta objetos de misión utilizables de tu bolsa.\n\nDebido al límite de acciones de estado, este módulo anula la barra 10 creada por ElvUI Extra Action Bars." -L["Toggles the display of the actionbars backdrop."] = "Alterna la visualización del fondo de las barras de acción." -L["The frame won't show unless you mouse over it."] = "El marco no se mostrará a menos que pases el ratón por encima." -L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Hereda el desvanecimiento global, pasar el ratón por encima, seleccionar objetivo, establecer foco, perder salud, entrar en combate eliminará la transparencia. De lo contrario, usará el nivel de transparencia en la configuración general de la barra de acción para el desvanecimiento global alfa." +L["Toggles the display of the actionbar's backdrop."] = "Alterna la visualización del fondo de las barras de acción." +L["The frame will not be displayed unless hovered over."] = "El marco no se mostrará a menos que pases el ratón por encima." +L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Hereda el desvanecimiento global, pasar el ratón por encima, seleccionar objetivo, establecer foco, perder salud, entrar en combate eliminará la transparencia. De lo contrario, usará el nivel de transparencia en la configuración general de la barra de acción para el desvanecimiento global alfa." L["The first button anchors itself to this point on the bar."] = "El primer botón se ancla a este punto en la barra." L["Right-click the item while holding the modifier to blacklist it. Blacklisted items will not show up on the bar.\nUse /questbarRestore to purge the blacklist."] = "Haz clic derecho en el objeto mientras mantienes presionado el modificador para añadirlo a la lista negra. Los objetos en la lista negra no aparecerán en la barra.\nUsa /questbarRestore para purgar la lista negra." -L["The amount of buttons to display."] = "La cantidad de botones a mostrar." -L["The amount of buttons to display per row."] = "La cantidad de botones a mostrar por fila." +L["The number of buttons to display."] = "La cantidad de botones a mostrar." +L["The number of buttons to display per row."] = "La cantidad de botones a mostrar por fila." L["The size of the action buttons."] = "El tamaño de los botones de acción." -L["The spacing between buttons."] = "El espacio entre botones." -L["The spacing between the backdrop and the buttons."] = "El espacio entre el fondo y los botones." -L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."] = "Multiplica la altura o el ancho del fondo por este valor. Esto es útil si deseas tener más de una barra detrás de un fondo." -L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"] = "Esto funciona como una macro, puedes ejecutar diferentes situaciones para hacer que la barra de acción se muestre/oculte de manera diferente.\n Ejemplo: '[combat] showhide'" -L["Adds anchoring options to movers' nudges."] = "Agrega opciones de anclaje a los empujones de los movedores." -L["Mod-clicking an item suggest a skill/item to process it."] = "Hacer clic con el modificador en un objeto sugiere una habilidad/objeto para procesarlo." -L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = +L["Spacing between the buttons."] = "El espacio entre botones." +L["Spacing between the backdrop and the buttons."] = "El espacio entre el fondo y los botones." +L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."] = "Multiplica la altura o el ancho del fondo por este valor. Esto es útil si deseas tener más de una barra detrás de un fondo." +L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"] = "Esto funciona como una macro, puedes ejecutar diferentes situaciones para hacer que la barra de acción se muestre/oculte de manera diferente.\n Ejemplo: '[combat] showhide'" +L["Adds anchoring options to the movers' nudges."] = "Agrega opciones de anclaje a los empujones de los movedores." +L["Mod-clicking an item suggests a skill/item to process it."] = "Hacer clic con el modificador en un objeto sugiere una habilidad/objeto para procesarlo." +L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = "Mantener presionado %s mientras se hace clic izquierdo en una pila la divide en dos; para combinar copias disponibles, haz clic derecho en su lugar.".. "\n\nTambién modifica el SplitStackFrame para usar un cuadro de edición en lugar de flechas." L["Extends the bags functionality."] = "Extiende la funcionalidad de las bolsas." -L["Handles automated repositioning of the newly received items."] = "Maneja el reposicionamiento automático de los objetos recién recibidos." -L["Default method: type > inventoryslotid > ilvl > name."] = "Método predeterminado: tipo > id de ranura de inventario > nivel de objeto > nombre." +L["Default method: type > inventory slot ID > item level > name."] = "Método predeterminado: tipo > id de ranura de inventario > nivel de objeto > nombre." L["Listed ItemIDs will not get sorted."] = "Los ID de objetos listados no se ordenarán." -L["Double-click the title text to minimize the section."] = "Haz doble clic en el texto del título para minimizar la sección." -L["Minimized section's line color."] = "Color de línea de la sección minimizada." L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"] = "Ej. Interface\\Icons\\INV_Misc_QuestionMark" L["Invalid condition format: "] = "Formato de condición inválido: " L["The generated custom sorting method did not return a function."] = "El método de ordenación personalizado generado no devolvió una función." @@ -98,26 +95,26 @@ L["The loaded custom sorting method did not return a function."] = "El método d L["Item received: "] = "Objeto recibido: " L[" added."] = " agregado." L[" removed."] = " eliminado." -L["Handles automated repositioning of the newly received items.".. +L["Handles the automated repositioning of the newly received items.".. "\nSyntax: filter@value\n\n".. "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. "Look up GetItemInfo API for more info on filters. ".. "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. "Example usage (priest t8 or Shadowmourne):\n".. "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. + "The below one notifies of the newly acquired items.\n\n".. "local icon = GetContainerItemInfo(bagID, slotID)\n".. "local _, link = GetItemInfo(itemID)\n".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. @@ -126,16 +123,16 @@ L["Handles automated repositioning of the newly received items.".. "Maneja el reposicionamiento automático de los objetos recién recibidos.".. "\nSintaxis: filtro@valor\n\n".. "Filtros disponibles:\n".. - "id@número - coincide con el ID del objeto,\n".. - "name@cadena - coincide con el nombre,\n".. - "subtype@cadena - coincide con el subtipo,\n".. - "ilvl@número - coincide con el nivel de objeto,\n".. - "uselevel@número - coincide con el nivel de equipo,\n".. - "quality@número - coincide con la calidad,\n".. - "equipslot@número - coincide con el ID de ranura de inventario,\n".. - "maxstack@número - coincide con el límite de apilamiento,\n".. - "price@número - coincide con el precio de venta,\n\n".. - "tooltip@cadena - coincide con el texto del tooltip,\n\n".. + " id@número - coincide con el ID del objeto,\n".. + " name@cadena - coincide con el nombre,\n".. + " subtype@cadena - coincide con el subtipo,\n".. + " ilvl@número - coincide con el nivel de objeto,\n".. + " uselevel@número - coincide con el nivel de equipo,\n".. + " quality@número - coincide con la calidad,\n".. + " equipslot@número - coincide con el ID de ranura de inventario,\n".. + " maxstack@número - coincide con el límite de apilamiento,\n".. + " price@número - coincide con el precio de venta,\n\n".. + " tooltip@cadena - coincide con el texto del tooltip,\n\n".. "Todas las coincidencias de cadena no distinguen entre mayúsculas y minúsculas y solo coinciden con los símbolos alfanuméricos. Se aplica la lógica estándar de Lua. ".. "Consulte la API GetItemInfo para obtener más información sobre los filtros. ".. "Use GetAuctionItemClasses y GetAuctionItemSubClasses (igual que en la Casa de Subastas) para obtener los valores localizados de tipos y subtipos.\n\n".. @@ -148,6 +145,47 @@ L["Handles automated repositioning of the newly received items.".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. "print('Objeto recibido: ' .. string)" +L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Sintaxis: filtro@valor\n\n".. + "Filtros disponibles:\n".. + " id@número - coincide con itemID,\n".. + " name@texto - coincide con nombre,\n".. + " type@texto - coincide con tipo,\n".. + " subtype@texto - coincide con subtipo,\n".. + " ilvl@número - coincide con nivel de objeto,\n".. + " uselevel@número - coincide con nivel de equipamiento,\n".. + " quality@número - coincide con calidad,\n".. + " equipslot@número - coincide con ID de ranura de inventario,\n".. + " maxstack@número - coincide con límite de acumulación,\n".. + " price@número - coincide con precio de venta,\n".. + " tooltip@texto - coincide con texto de descripción.\n\n".. + "Todas las coincidencias de texto no distinguen entre mayúsculas y minúsculas y solo coinciden con símbolos alfanuméricos.\n".. + "Se aplica la lógica lua estándar para ramificación (y/o/paréntesis/etc.).\n\n".. + "Ejemplo de uso (sacerdote t8 o Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["Available Item Types"] = "Tipos de objetos disponibles" +L["Lists all available item subtypes for each available item type."] = + "Lista todos los subtipos de objetos disponibles para cada tipo de objeto disponible." +L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."] = + "Mantener esta tecla al interactuar con un comerciante compra todos los artículos que cumplen con el método de compra automática.\n".. + "Haz clic con mod en la entrada de la lista de compra para comprar solo uno de los artículos, sin importar la regla '@cantidad'." L["Default method: type > inventoryslotid > ilvl > name.\n\n".. "Accepts custom functions (bagID and slotID are available at the a/b.bagID/slotID).\n\n".. "function(a,b)\n".. @@ -171,7 +209,7 @@ L["Syntax:".. "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -181,13 +219,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. @@ -210,13 +248,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(el jugador ha ganado/perdido un aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Hechizo malo')".. "\nthen print(UnitName('party'..i)..' está afectado!')".. @@ -224,7 +262,7 @@ L["Syntax:".. "\n\nEste módulo analiza cadenas, así que trate de que su código siga estrictamente la sintaxis, o de lo contrario podría no funcionar." L["Highlights auras."] = "Destaca auras." L["E.g. 42292"] = "Por ejemplo, 42292" -L["Aplies highlights to all auras passing the selected filter."] = "Destaca todas las auras que pasan el filtro seleccionado." +L["Applies highlights to all auras passing the selected filter."] = "Destaca todas las auras que pasan el filtro seleccionado." L["Priority: spell, filter, curable/stealable."] = "Prioridad: hechizo, filtro, curable/robable." L["If toggled, the GLOBAL Spell or Filter entry values would be used."] = "Si se activa, se usarán los valores GLOBAL de Hechizo o Filtro." L["Makes auras grow sideswise."] = "Hace que las auras crezcan lateralmente." @@ -236,7 +274,15 @@ L["Right-click a player buff to cancel it."] = "Haz clic derecho en un buff del L["Disables debuffs desaturation."] = "Desactiva la desaturación de los debuffs." L["Saturated Debuffs"] = "Debuffs Saturados" L["Confirm Rolls"] = "Confirmar tiradas" -L["Quest Items and Money"] = "Objetos de misión y dinero" +L["Auto Pickup"] = "Recogida automática" +L["Swift Buy"] = "Compra rápida" +L["Buys out items automatically."] = "Compra objetos automáticamente." +L["Failsafe"] = "Seguro de fallos" +L["Enables popup confirmation dialog."] = "Habilita el cuadro de diálogo de confirmación emergente." +L["Add Set"] = "Añadir conjunto" +L["Delete Set"] = "Eliminar conjunto" +L["Select Set"] = "Seleccionar conjunto" +L["Auto Buy"] = "Compra automática" L["Fill Delete"] = "Rellenar borrado" L["Gossip"] = "Diálogo" L["Accept Quest"] = "Aceptar misión" @@ -272,7 +318,6 @@ L["Select Container Type"] = "Seleccionar tipo de contenedor" L["Settings"] = "Configuración" L["Add Section"] = "Añadir sección" L["Delete Section"] = "Eliminar sección" -L["Section Length"] = "Longitud de sección" L["Select Section"] = "Seleccionar sección" L["Section Priority"] = "Prioridad de sección" L["Section Spacing"] = "Espaciado de sección" @@ -280,8 +325,6 @@ L["Collection Method"] = "Método de colección" L["Sorting Method"] = "Método de ordenación" L["Ignore Item (by ID)"] = "Ignorar objeto (por ID)" L["Remove Ignored"] = "Eliminar ignorados" -L["Minimize"] = "Minimizar" -L["Line Color"] = "Color de línea" L["Title"] = "Título" L["Color"] = "Color" L["Attach to Icon"] = "Adjuntar al icono" @@ -446,13 +489,10 @@ L["Add Texture Path"] = "Agregar ruta de textura" L["Remove Selected Texture"] = "Eliminar textura seleccionada" L["Titles"] = "Títulos" L["Reaction Color"] = "Color de reacción" -L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"] = - "Mantén presionado esto mientras usas el comando /addOccupation para borrar la lista de la ocupación actual del objetivo/ratón sobre.\n¡No olvides desvincular la combinación de modificador+tecla!" L["Color based on reaction type."] = "Color basado en el tipo de reacción." L["Nameplates"] = "Placas de nombre" L["Unitframes"] = "Marcos de unidad" -L["An icon similar to the minimap search.\n\nTooltip scanning, might not be precise.\n\nFor consistency reasons, no keywards are added by defult, use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."] = - "Un icono similar a la búsqueda del minimapa.\n\nEscaneo de tooltips, puede no ser preciso.\n\nPor razones de consistencia, no se agregan palabras clave por defecto, usa el comando /addOccupation para marcar las apropiadas tú mismo (solo necesitas hacerlo una vez por texto de ocupación único)." +L["An icon similar to the minimap search."] = "Un icono similar a la búsqueda del minimapa." L["Displays player guild text."] = "Muestra el texto de la hermandad del jugador." L["Displays NPC occupation text."] = "Muestra el texto de ocupación del PNJ." L["Strata"] = "Estrato" @@ -475,40 +515,6 @@ L["Unmark all plates."] = "Desmarca todas las placas." L["Usage: '/qmark' macro bound to a key of your choice.\n\nDon't forget to also unbind your modifier keybinds!"] = "Uso: macro '/qmark' vinculada a una tecla de tu elección.\n\n¡No olvides desvincular también tus atajos de modificador!" L["Use Backdrop"] = "Usar fondo" -L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."] = - "Uso:\n%%d=%%s\n\n%%d - índice de la lista a continuación\n%%s - palabras clave para buscar\n\nÍndices de iconos:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nTambién disponible como un comando '/addOccupation %%d' donde %%d es un índice de icono opcional. ".. - "Si no se proporciona un índice, este comando recorrerá todos los iconos disponibles. Funciona en TARGET o MOUSEOVER, priorizando este último." L["Linked Style Filter Triggers"] = "Disparadores de Filtro de Estilo Vinculado" L["Select Link"] = "Seleccionar Enlace" L["New Link"] = "Nuevo Enlace" @@ -613,7 +619,7 @@ L["Disable Event"] = "Deshabilitar Evento" L["School"] = "Escuela" L["Use School Colors"] = "Usar Colores de Escuela" L["Colors"] = "Colores" -L["Colors (School)"] = "Colores (Escuela)" +L["Color (School)"] = "Color (Escuela)" L["Animation Type"] = "Tipo de Animación" L["Custom Animation"] = "Animación Personalizada" L["Flag Settings"] = "Configuración de Banderas" @@ -699,7 +705,7 @@ L["Rare Elite"] = "Élite Raro" L["Class Spec Icons"] = "Iconos de Especialización de Clase" L["Classification Textures"] = "Texturas de Clasificación" L["Use Nameplates' Icons"] = "Usar Iconos de Placas de Nombre" -L["Color enemy npc icon based on the unit type."] = "Colorear icono de NPC enemigo basado en el tipo de unidad." +L["Color enemy NPC icon based on the unit type."] = "Colorear icono de NPC enemigo basado en el tipo de unidad." L["Strata and Level"] = "Estrato y Nivel" L["Warrior"] = "Guerrero" L["Warlock"] = "Brujo" @@ -771,7 +777,6 @@ L["On meeting multiple conditions, colors from the tab with the highest priority L["Copy Tab"] = "Copiar Pestaña" L["Select a tab to copy its settings onto the current tab."] = "Selecciona una pestaña para copiar sus ajustes en la pestaña actual." L["Flash"] = "Destello" -L["Toggle color flash for the current tab."] = "Alternar destello de color para la pestaña actual." L["Speed"] = "Velocidad" L["Glow"] = "Resplandor" L["Determines which glow to apply when statusbars are not detached from frame."] = "Determina qué resplandor aplicar cuando las barras de estado no están separadas del marco." @@ -788,7 +793,7 @@ L["Disabled unless classbar is enabled."] = "Desactivado a menos que la barra de L["InfoPanel Color"] = "Color del Panel de Información" L["Disabled unless infopanel is enabled."] = "Desactivado a menos que el panel de información esté habilitado." L["ClassBar Adapt To"] = "Adaptar Barra de Clase A" -L["Copies color of the selected bar."] = "Copia el color de la barra seleccionada." +L["Copies the color of the selected bar."] = "Copia el color de la barra seleccionada." L["InfoPanel Adapt To"] = "Adaptar Panel de Información A" L["Override Mode"] = "Modo de Anulación" L["'None' - threat borders highlight will be prioritized over this one".. @@ -806,33 +811,43 @@ L["Handle only player combat log events."] = "Solo manejar eventos del registro L["Rotate Icon"] = "Rotar icono" L["Usage example:".. "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/5]@@ - devuelve verdadero/falso basado en si la pestaña en cuestión (en el ejemplo anterior: 'player' - unidad objetivo; 'Power' - barra de estado objetivo; '3' - pestaña objetivo) está activa o no (mencionar la misma unidad/grupo está desactivado; no es recursivo)".. - "\n(>/>=/<=/5]@@ - devuelve verdadero/falso basado en si la pestaña en cuestión ".. + "(en el ejemplo anterior: 'player' - unidad objetivo; 'Power' - barra de estado objetivo; '3' - pestaña objetivo) está activa o no".. + "\n(>/>=/<=/=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = + "Maneja la posición automática de los objetos.\n".. + "Sintaxis: filter@value\n\n".. + "Filtros disponibles:\n".. + " id@number - coincide con itemID,\n".. + " name@string - coincide con nombre,\n".. + " type@string - coincide con tipo,\n".. + " subtype@string - coincide con subtipo,\n".. + " ilvl@number - coincide con ilvl,\n".. + " uselevel@number - coincide con nivel de equipamiento,\n".. + " quality@number - coincide con calidad,\n".. + " equipslot@number - coincide con InventorySlotID,\n".. + " maxstack@number - coincide con límite de apilamiento,\n".. + " price@number - coincide con precio de venta,\n".. + " tooltip@string - coincide con texto de tooltip,\n".. + " set@setName - coincide con objetos de conjunto de equipamiento.\n\n".. + "Todas las coincidencias de cadenas no son sensibles a mayúsculas y minúsculas y solo coinciden con los símbolos alfanuméricos.\n".. + "La lógica estándar de Lua para ramificaciones (y/o/paréntesis/etc.) se aplica.\n\n".. + "Ejemplo de uso (sacerdote t8 o Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Acepta funciones personalizadas (bagID, slotID, itemID están expuestos)\n".. + "El siguiente notifica sobre los objetos recién adquiridos.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item recibido: ' .. string)" +L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Sintaxis: filter@value@amount\n\n".. + "Filtros disponibles:\n".. + " id@number@amount(+)/+ - coincide con itemID,\n".. + " name@string@amount(+)/+ - coincide con nombre,\n".. + " type@string@amount(+)/+ - coincide con tipo,\n".. + " subtype@string@amount(+)/+ - coincide con subtipo,\n".. + " ilvl@number@amount(+)/+ - coincide con ilvl,\n".. + " uselevel@number@amount(+)/+ - coincide con nivel de equipamiento,\n".. + " quality@number@amount(+)/+ - coincide con calidad,\n".. + " equipslot@number@amount(+)/+ - coincide con InventorySlotID,\n".. + " maxstack@number@amount(+)/+ - coincide con límite de apilamiento,\n".. + " price@number@amount(+)/+ - coincide con precio de venta,\n".. + " tooltip@string@amount(+)/+ - coincide con texto de tooltip.\n\n".. + "La parte opcional 'amount' podría ser:\n".. + " un número - para comprar una cantidad estática,\n".. + " un signo + - para reponer el apilamiento parcial existente o comprar uno nuevo,\n".. + " ambos (por ejemplo, 5+) - para comprar suficientes objetos para alcanzar un total especificado (en este caso, 5),\n".. + " omitido - por defecto es 1.\n\n".. + "Todas las coincidencias de cadenas no son sensibles a mayúsculas y minúsculas y solo coinciden con los símbolos alfanuméricos.\n".. + "La lógica estándar de Lua para ramificaciones (y/o/paréntesis/etc.) se aplica.\n\n".. + "Ejemplo de uso (sacerdote t8 o Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["PERIODIC"] = "PERIODICO" +L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."] = "Mantén esta tecla presionada mientras usas el comando /addOccupation para limpiar la lista del NPC objetivo/ratón actual." +L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."] = "Usa el comando de barra /addOccupation mientras apuntas/te mueves sobre un NPC para agregarlo a la lista. Usa nuevamente para alternar." +L["Style Filter Icons"] = "Iconos de Filtro de Estilo" +L["Custom icons for the style filter."] = "Iconos personalizados para el filtro de estilo." +L["Whitelist"] = "Lista blanca" +L["X Direction"] = "Dirección X" +L["Y Direction"] = "Dirección Y" +L["Create Icon"] = "Crear ícono" +L["Delete Icon"] = "Eliminar ícono" +L["0 to match frame width."] = "0 para coincidir con el ancho del marco." +L["Remove a NPC"] = "Eliminar un NPC" +L["Change a NPC's Occupation"] = "Cambiar la ocupación de un NPC" +L["...to the currently selected one."] = "...al actualmente seleccionado." +L["Select Occupation"] = "Seleccionar ocupación" \ No newline at end of file diff --git a/Locales/frFR.lua b/Locales/frFR.lua index 8766694..e512644 100644 --- a/Locales/frFR.lua +++ b/Locales/frFR.lua @@ -2,16 +2,16 @@ local E = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, Global local L = E.Libs.ACL:NewLocale("ElvUI", "frFR") L["Hits the 'Confirm' button automatically."] = "Appuie automatiquement sur le bouton 'Confirmer'." -L["Picks up quest items and money automatically."] = "Ramasse automatiquement les objets de quête et l'argent." -L["Fills 'DELETE' field automatically."] = "Remplit automatiquement le champ 'SUPPRIMER'." -L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."] = "Sélectionne la première option de dialogue si c'est la seule disponible, sauf si un modificateur est maintenu.\nAttention aux déclencheurs d'événements importants, il n'y a pas de mécanisme de sécurité." +L["Picks up items and money automatically."] = "Ramasse automatiquement les objets et l'argent." +L["Automatically fills the 'DELETE' field."] = "Remplit automatiquement le champ 'SUPPRIMER'." +L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."] = "Sélectionne la première option de dialogue si c'est la seule disponible, sauf si un modificateur est maintenu.\nAttention aux déclencheurs d'événements importants, il n'y a pas de mécanisme de sécurité." L["Accepts and turns in quests automatically while holding a modifier."] = "Accepte et rend les quêtes automatiquement en maintenant un modificateur." L["Loot info wiped."] = "Informations de butin effacées." L["/lootinfo slash command to get a quick rundown of the recent lootings.\n\nUsage: /lootinfo Apple 60\n'Apple' - item/player name \n(search @self to get player loot)\n'60' - \ntime limit (<60 seconds ago), optional,\n/lootinfo !wipe - purge loot cache."] = "Commande /lootinfo pour obtenir un résumé rapide des butins récents.\n\nUtilisation: /lootinfo Pomme 60\n'Pomme' - nom de l'objet/joueur \n(rechercher @self pour obtenir le butin du joueur)\n'60' - \nlimite de temps (<60 secondes), optionnel,\n/lootinfo !wipe - purger le cache de butin." -L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Colore les noms des amis en ligne et des membres de la guilde dans certains messages et stylise les jets.\nLes bulles de discussion déjà traitées ne seront pas stylisées avant un /reload." +L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Colore les noms des amis en ligne et des membres de la guilde dans certains messages et stylise les jets.\nLes bulles de discussion déjà traitées ne seront pas stylisées avant un /reload." L["Colors loot roll messages for you and other players."] = "Colore les messages de jets de butin pour vous et les autres joueurs." L["Loot rolls icon size."] = "Taille de l'icône des jets de butin." -L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Restyler les barres de butin.\nNécessite que 'Jet de butin' (Général -> Améliorations BlizzUI -> Jet de butin) soit activé (activer ce module l'active automatiquement)." +L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Restyler les barres de butin.\nNécessite que 'Jet de butin' (Général -> Améliorations BlizzUI -> Jet de butin) soit activé (activer ce module l'active automatiquement)." L["Displays the name of the player pinging the minimap."] = "Affiche le nom du joueur qui ping la minicarte." L["Displays the currently held currency amount next to the item prices."] = "Affiche le montant de la monnaie actuellement détenue à côté des prix des objets." L["Narrows down the World(..Frame)."] = "Réduit le World(..Frame)." @@ -27,7 +27,7 @@ L["Adds shadows to all of the frames.\nDoes nothing unless you replace your ElvU L["Combat state notification alerts."] = "Alertes de notification d'état de combat." L["Custom editbox position and size."] = "Position et taille personnalisées de la zone de saisie." L["Usage:".. - "\n/tnote list - returns all eixting notes".. + "\n/tnote list - returns all existing notes".. "\n/tnote wipe - clears all existing notes".. "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. "\n/tnote 1 get - same as set, returns existing notes".. @@ -68,29 +68,26 @@ L["Usage:".. "\n (1-percentage)*255, percentage*255)" L["Adds an icon next to chat hyperlinks."] = "Ajoute une icône à côté des hyperliens du chat." L["A new action bar that collects usable quest items from your bag.\n\nDue to state actions limit, this module overrides bar10 created by ElvUI Extra Action Bars."] = "Une nouvelle barre d'action qui collecte les objets de quête utilisables de votre sac.\n\nEn raison de la limite d'actions d'état, ce module remplace la barre 10 créée par ElvUI Extra Action Bars." -L["Toggles the display of the actionbars backdrop."] = "Active/désactive l'affichage de l'arrière-plan des barres d'action." -L["The frame won't show unless you mouse over it."] = "Le cadre ne s'affichera que lorsque vous passez la souris dessus." -L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Hérite du fondu global, passer la souris dessus, cibler, définir le focus, perdre de la santé, entrer en combat supprimera la transparence. Sinon, il utilisera le niveau de transparence dans les paramètres généraux de la barre d'action pour le fondu global alpha." +L["Toggles the display of the actionbar's backdrop."] = "Active/désactive l'affichage de l'arrière-plan des barres d'action." +L["The frame will not be displayed unless hovered over."] = "Le cadre ne s'affichera que lorsque vous passez la souris dessus." +L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Hérite du fondu global, passer la souris dessus, cibler, définir le focus, perdre de la santé, entrer en combat supprimera la transparence. Sinon, il utilisera le niveau de transparence dans les paramètres généraux de la barre d'action pour le fondu global alpha." L["The first button anchors itself to this point on the bar."] = "Le premier bouton s'ancre à ce point sur la barre." L["Right-click the item while holding the modifier to blacklist it. Blacklisted items will not show up on the bar.\nUse /questbarRestore to purge the blacklist."] = "Faites un clic droit sur l'objet tout en maintenant le modificateur pour le mettre sur liste noire. Les objets sur liste noire n'apparaîtront pas sur la barre.\nUtilisez /questbarRestore pour purger la liste noire." -L["The amount of buttons to display."] = "Le nombre de boutons à afficher." -L["The amount of buttons to display per row."] = "Le nombre de boutons à afficher par ligne." +L["The number of buttons to display."] = "Le nombre de boutons à afficher." +L["The number of buttons to display per row."] = "Le nombre de boutons à afficher par ligne." L["The size of the action buttons."] = "La taille des boutons d'action." -L["The spacing between buttons."] = "L'espacement entre les boutons." -L["The spacing between the backdrop and the buttons."] = "L'espacement entre l'arrière-plan et les boutons." -L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."] = "Multiplie la hauteur ou la largeur de l'arrière-plan par cette valeur. C'est utile si vous souhaitez avoir plus d'une barre derrière un arrière-plan." -L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"] = "Cela fonctionne comme une macro, vous pouvez exécuter différentes situations pour faire apparaître/disparaître la barre d'action différemment.\n Exemple : '[combat] showhide'" -L["Adds anchoring options to movers' nudges."] = "Ajoute des options d'ancrage aux déplacements des mouveurs." -L["Mod-clicking an item suggest a skill/item to process it."] = "Cliquer avec le modificateur sur un objet suggère une compétence/objet pour le traiter." -L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = +L["Spacing between the buttons."] = "L'espacement entre les boutons." +L["Spacing between the backdrop and the buttons."] = "L'espacement entre l'arrière-plan et les boutons." +L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."] = "Multiplie la hauteur ou la largeur de l'arrière-plan par cette valeur. C'est utile si vous souhaitez avoir plus d'une barre derrière un arrière-plan." +L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"] = "Cela fonctionne comme une macro, vous pouvez exécuter différentes situations pour faire apparaître/disparaître la barre d'action différemment.\n Exemple : '[combat] showhide'" +L["Adds anchoring options to the movers' nudges."] = "Ajoute des options d'ancrage aux déplacements des mouveurs." +L["Mod-clicking an item suggests a skill/item to process it."] = "Cliquer avec le modificateur sur un objet suggère une compétence/objet pour le traiter." +L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = "Maintenir %s tout en faisant un clic gauche sur une pile la divise en deux; pour combiner les copies disponibles, faites un clic droit à la place.".. "\n\nModifie également le SplitStackFrame pour utiliser une zone de saisie au lieu de flèches." L["Extends the bags functionality."] = "Étend la fonctionnalité des sacs." -L["Handles automated repositioning of the newly received items."] = "Gère le repositionnement automatique des objets nouvellement reçus." -L["Default method: type > inventoryslotid > ilvl > name."] = "Méthode par défaut : type > id d'emplacement d'inventaire > niveau d'objet > nom." +L["Default method: type > inventory slot ID > item level > name."] = "Méthode par défaut : type > id d'emplacement d'inventaire > niveau d'objet > nom." L["Listed ItemIDs will not get sorted."] = "Les ID d'objets listés ne seront pas triés." -L["Double-click the title text to minimize the section."] = "Double-cliquez sur le texte du titre pour minimiser la section." -L["Minimized section's line color."] = "Couleur de ligne de la section minimisée." L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"] = "Ex. Interface\\Icons\\INV_Misc_QuestionMark" L["Invalid condition format: "] = "Format de condition invalide : " L["The generated custom sorting method did not return a function."] = "La méthode de tri personnalisée générée n'a pas retourné de fonction." @@ -98,26 +95,26 @@ L["The loaded custom sorting method did not return a function."] = "La méthode L["Item received: "] = "Objet reçu : " L[" added."] = " ajouté." L[" removed."] = " supprimé." -L["Handles automated repositioning of the newly received items.".. +L["Handles the automated repositioning of the newly received items.".. "\nSyntax: filter@value\n\n".. "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. "Look up GetItemInfo API for more info on filters. ".. "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. "Example usage (priest t8 or Shadowmourne):\n".. "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. + "The below one notifies of the newly acquired items.\n\n".. "local icon = GetContainerItemInfo(bagID, slotID)\n".. "local _, link = GetItemInfo(itemID)\n".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. @@ -126,16 +123,16 @@ L["Handles automated repositioning of the newly received items.".. "Gère le repositionnement automatique des objets nouvellement reçus.".. "\nSyntaxe: filtre@valeur\n\n".. "Filtres disponibles:\n".. - "id@nombre - correspond à l'ID de l'objet,\n".. - "name@chaîne - correspond au nom,\n".. - "subtype@chaîne - correspond au sous-type,\n".. - "ilvl@nombre - correspond au niveau d'objet,\n".. - "uselevel@nombre - correspond au niveau d'équipement,\n".. - "quality@nombre - correspond à la qualité,\n".. - "equipslot@nombre - correspond à l'ID d'emplacement d'inventaire,\n".. - "maxstack@nombre - correspond à la limite de pile,\n".. - "price@nombre - correspond au prix de vente,\n\n".. - "tooltip@chaîne - correspond au texte de l'infobulle,\n\n".. + " id@nombre - correspond à l'ID de l'objet,\n".. + " name@chaîne - correspond au nom,\n".. + " subtype@chaîne - correspond au sous-type,\n".. + " ilvl@nombre - correspond au niveau d'objet,\n".. + " uselevel@nombre - correspond au niveau d'équipement,\n".. + " quality@nombre - correspond à la qualité,\n".. + " equipslot@nombre - correspond à l'ID d'emplacement d'inventaire,\n".. + " maxstack@nombre - correspond à la limite de pile,\n".. + " price@nombre - correspond au prix de vente,\n\n".. + " tooltip@chaîne - correspond au texte de l'infobulle,\n\n".. "Toutes les correspondances de chaînes ne sont pas sensibles à la casse et ne correspondent qu'aux symboles alphanumériques. La logique Lua standard s'applique. ".. "Consultez l'API GetItemInfo pour plus d'informations sur les filtres. ".. "Utilisez GetAuctionItemClasses et GetAuctionItemSubClasses (comme dans l'HV) pour obtenir les valeurs localisées des types et sous-types.\n\n".. @@ -148,6 +145,47 @@ L["Handles automated repositioning of the newly received items.".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. "print('Objet reçu: ' .. string)" +L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Syntaxe: filtre@valeur\n\n".. + "Filtres disponibles:\n".. + " id@nombre - correspond à l'ID de l'objet,\n".. + " name@texte - correspond au nom,\n".. + " type@texte - correspond au type,\n".. + " subtype@texte - correspond au sous-type,\n".. + " ilvl@nombre - correspond au niveau d'objet,\n".. + " uselevel@nombre - correspond au niveau d'équipement,\n".. + " quality@nombre - correspond à la qualité,\n".. + " equipslot@nombre - correspond à l'ID d'emplacement d'inventaire,\n".. + " maxstack@nombre - correspond à la limite de pile,\n".. + " price@nombre - correspond au prix de vente,\n".. + " tooltip@texte - correspond au texte de l'infobulle.\n\n".. + "Toutes les correspondances de texte ne sont pas sensibles à la casse et ne correspondent qu'aux symboles alphanumériques.\n".. + "La logique lua standard pour les branchements (et/ou/parenthèses/etc.) s'applique.\n\n".. + "Exemple d'utilisation (prêtre t8 ou Deuillelombre):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["Available Item Types"] = "Types d'objets disponibles" +L["Lists all available item subtypes for each available item type."] = + "Liste tous les sous-types d'objets disponibles pour chaque type d'objet disponible." +L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."] = + "Maintenir cette touche en interagissant avec un marchand achète tous les articles qui passent le filtre d'Achat automatique.\n".. + "Mod-cliquez sur une entrée de la liste pour acheter un seul des articles, peu importe la règle '@quantité'." L["Default method: type > inventoryslotid > ilvl > name.\n\n".. "Accepts custom functions (bagID and slotID are available at the a/b.bagID/slotID).\n\n".. "function(a,b)\n".. @@ -171,7 +209,7 @@ L["Syntax:".. "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -181,13 +219,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. @@ -210,13 +248,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(le joueur a gagné/perdu une aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Mauvais sort')".. "\nthen print(UnitName('party'..i)..' est affecté!')".. @@ -224,7 +262,7 @@ L["Syntax:".. "\n\nCe module analyse les chaînes, donc essayez de faire suivre strictement la syntaxe à votre code, sinon il pourrait ne pas fonctionner." L["Highlights auras."] = "Met en surbrillance les auras." L["E.g. 42292"] = "Par exemple, 42292" -L["Aplies highlights to all auras passing the selected filter."] = "Met en surbrillance toutes les auras passant le filtre sélectionné." +L["Applies highlights to all auras passing the selected filter."] = "Met en surbrillance toutes les auras passant le filtre sélectionné." L["Priority: spell, filter, curable/stealable."] = "Priorité : sort, filtre, soignable/volable." L["If toggled, the GLOBAL Spell or Filter entry values would be used."] = "Si activé, les valeurs GLOBAL de Sort ou Filtre seront utilisées." L["Makes auras grow sideswise."] = "Fait croître les auras latéralement." @@ -236,7 +274,15 @@ L["Right-click a player buff to cancel it."] = "Cliquez avec le bouton droit sur L["Disables debuffs desaturation."] = "Désactive la désaturation des débuffs." L["Saturated Debuffs"] = "Débuffs Saturés" L["Confirm Rolls"] = "Confirmer les jets" -L["Quest Items and Money"] = "Objets de quête et argent" +L["Auto Pickup"] = "Ramassage automatique" +L["Swift Buy"] = "Achat rapide" +L["Buys out items automatically."] = "Achète automatiquement des articles." +L["Failsafe"] = "Sécurité" +L["Enables popup confirmation dialog."] = "Active la boîte de dialogue de confirmation." +L["Add Set"] = "Ajouter un ensemble" +L["Delete Set"] = "Supprimer l'ensemble" +L["Select Set"] = "Sélectionner un ensemble" +L["Auto Buy"] = "Achat automatique" L["Fill Delete"] = "Remplir suppression" L["Gossip"] = "Dialogue" L["Accept Quest"] = "Accepter quête" @@ -272,7 +318,6 @@ L["Select Container Type"] = "Sélectionner le type de conteneur" L["Settings"] = "Paramètres" L["Add Section"] = "Ajouter une section" L["Delete Section"] = "Supprimer la section" -L["Section Length"] = "Longueur de la section" L["Select Section"] = "Sélectionner la section" L["Section Priority"] = "Priorité de la section" L["Section Spacing"] = "Espacement des sections" @@ -280,8 +325,6 @@ L["Collection Method"] = "Méthode de collecte" L["Sorting Method"] = "Méthode de tri" L["Ignore Item (by ID)"] = "Ignorer l'objet (par ID)" L["Remove Ignored"] = "Supprimer les ignorés" -L["Minimize"] = "Réduire" -L["Line Color"] = "Couleur de ligne" L["Title"] = "Titre" L["Color"] = "Couleur" L["Attach to Icon"] = "Attacher à l'icône" @@ -447,13 +490,10 @@ L["Add Texture Path"] = "Ajouter un chemin de texture" L["Remove Selected Texture"] = "Supprimer la texture sélectionnée" L["Titles"] = "Titres" L["Reaction Color"] = "Couleur de réaction" -L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"] = - "Maintenez ceci tout en utilisant la commande /addOccupation pour effacer la liste de l'occupation actuelle de la cible/survol.\nN'oubliez pas de délier la combinaison modificateur+touche !" L["Color based on reaction type."] = "Couleur basée sur le type de réaction." L["Nameplates"] = "Barres d'informations" L["Unitframes"] = "Cadres d'unité" -L["An icon similar to the minimap search.\n\nTooltip scanning, might not be precise.\n\nFor consistency reasons, no keywards are added by defult, use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."] = - "Une icône similaire à la recherche sur la minicarte.\n\nAnalyse des infobulles, peut ne pas être précise.\n\nPour des raisons de cohérence, aucun mot-clé n'est ajouté par défaut, utilisez la commande /addOccupation pour marquer vous-même les appropriés (à faire une seule fois par texte d'occupation unique)." +L["An icon similar to the minimap search."] = "Une icône similaire à la recherche sur la minicarte." L["Displays player guild text."] = "Affiche le texte de guilde du joueur." L["Displays NPC occupation text."] = "Affiche le texte d'occupation du PNJ." L["Strata"] = "Strate" @@ -476,40 +516,6 @@ L["Unmark all plates."] = "Démarque toutes les barres d'informations." L["Usage: '/qmark' macro bound to a key of your choice.\n\nDon't forget to also unbind your modifier keybinds!"] = "Utilisation : macro '/qmark' liée à une touche de votre choix.\n\nN'oubliez pas de délier également vos raccourcis de modificateur !" L["Use Backdrop"] = "Utiliser l'arrière-plan" -L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."] = - "Utilisation :\n%%d=%%s\n\n%%d - index de la liste ci-dessous\n%%s - mots-clés à rechercher\n\nIndices des icônes :".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nÉgalement disponible en tant que commande '/addOccupation %%d' où %%d est un indice d'icône facultatif.".. - "Si aucun indice n'est fourni, cette commande parcourra toutes les icônes disponibles. Fonctionne sur TARGET ou MOUSEOVER, en priorisant ce dernier." L["Linked Style Filter Triggers"] = "Déclencheurs de filtre de style lié" L["Select Link"] = "Sélectionner le lien" L["New Link"] = "Nouveau lien" @@ -614,7 +620,7 @@ L["Disable Event"] = "Désactiver l'événement" L["School"] = "École" L["Use School Colors"] = "Utiliser les couleurs d'école" L["Colors"] = "Couleurs" -L["Colors (School)"] = "Couleurs (École)" +L["Color (School)"] = "Couleur (École)" L["Animation Type"] = "Type d'animation" L["Custom Animation"] = "Animation personnalisée" L["Flag Settings"] = "Paramètres de drapeau" @@ -700,7 +706,7 @@ L["Rare Elite"] = "Élite Rare" L["Class Spec Icons"] = "Icônes de Spécialisation de Classe" L["Classification Textures"] = "Textures de Classification" L["Use Nameplates' Icons"] = "Utiliser les Icônes des Barres de Nom" -L["Color enemy npc icon based on the unit type."] = "Colorer l'icône du PNJ ennemi en fonction du type d'unité." +L["Color enemy NPC icon based on the unit type."] = "Colorer l'icône du PNJ ennemi en fonction du type d'unité." L["Strata and Level"] = "Strate et Niveau" L["Warrior"] = "Guerrier" L["Warlock"] = "Démoniste" @@ -772,7 +778,6 @@ L["On meeting multiple conditions, colors from the tab with the highest priority L["Copy Tab"] = "Copier l'Onglet" L["Select a tab to copy its settings onto the current tab."] = "Sélectionnez un onglet pour copier ses paramètres sur l'onglet actuel." L["Flash"] = "Flash" -L["Toggle color flash for the current tab."] = "Basculer le flash de couleur pour l'onglet actuel." L["Speed"] = "Vitesse" L["Glow"] = "Lueur" L["Determines which glow to apply when statusbars are not detached from frame."] = "Détermine quelle lueur appliquer lorsque les barres d'état ne sont pas détachées du cadre." @@ -789,7 +794,7 @@ L["Disabled unless classbar is enabled."] = "Désactivé sauf si la barre de cla L["InfoPanel Color"] = "Couleur du Panneau d'Information" L["Disabled unless infopanel is enabled."] = "Désactivé sauf si le panneau d'information est activé." L["ClassBar Adapt To"] = "Adapter la Barre de Classe À" -L["Copies color of the selected bar."] = "Copie la couleur de la barre sélectionnée." +L["Copies the color of the selected bar."] = "Copie la couleur de la barre sélectionnée." L["InfoPanel Adapt To"] = "Adapter le Panneau d'Information À" L["Override Mode"] = "Mode de Remplacement" L["'None' - threat borders highlight will be prioritized over this one".. @@ -807,33 +812,43 @@ L["Handle only player combat log events."] = "Gérer uniquement les événements L["Rotate Icon"] = "Faire pivoter l'icône" L["Usage example:".. "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/5]@@ - renvoie vrai/faux selon que l'onglet en question (dans l'exemple ci-dessus : 'player' - unité cible ; 'Power' - barre d'état cible ; '3' - onglet cible) est actif ou non (la mention de la même unité/groupe est désactivée ; n'est pas récursif)".. - "\n(>/>=/<=/5]@@ - renvoie vrai/faux selon que l'onglet en question ".. + "(dans l'exemple ci-dessus : 'player' - unité cible ; 'Power' - barre d'état cible ; '3' - onglet cible) est actif ou non".. + "\n(>/>=/<=/=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = + "Gère le positionnement automatique des objets.\n".. + "Syntaxe : filter@value\n\n".. + "Filtres disponibles :\n".. + " id@number - correspond à itemID,\n".. + " name@string - correspond au nom,\n".. + " type@string - correspond au type,\n".. + " subtype@string - correspond au sous-type,\n".. + " ilvl@number - correspond à ilvl,\n".. + " uselevel@number - correspond au niveau d'équipement,\n".. + " quality@number - correspond à la qualité,\n".. + " equipslot@number - correspond à InventorySlotID,\n".. + " maxstack@number - correspond à la limite de pile,\n".. + " price@number - correspond au prix de vente,\n".. + " tooltip@string - correspond au texte de l'info-bulle,\n".. + " set@setName - correspond aux objets de l'ensemble d'équipement.\n\n".. + "Toutes les correspondances de chaînes ne sont pas sensibles à la casse et ne correspondent qu'aux symboles alphanumériques.\n".. + "La logique standard de Lua pour les branches (et/ou/parenthèses/etc.) s'applique.\n\n".. + "Exemple d'utilisation (prêtre t8 ou Shadowmourne) :\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepte des fonctions personnalisées (bagID, slotID, itemID sont exposés)\n".. + "Le suivant notifie des objets nouvellement acquis.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Objet reçu : ' .. string)" +L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Syntaxe : filter@value@amount\n\n".. + "Filtres disponibles :\n".. + " id@number@amount(+)/+ - correspond à itemID,\n".. + " name@string@amount(+)/+ - correspond au nom,\n".. + " type@string@amount(+)/+ - correspond au type,\n".. + " subtype@string@amount(+)/+ - correspond au sous-type,\n".. + " ilvl@number@amount(+)/+ - correspond à ilvl,\n".. + " uselevel@number@amount(+)/+ - correspond au niveau d'équipement,\n".. + " quality@number@amount(+)/+ - correspond à la qualité,\n".. + " equipslot@number@amount(+)/+ - correspond à InventorySlotID,\n".. + " maxstack@number@amount(+)/+ - correspond à la limite de pile,\n".. + " price@number@amount(+)/+ - correspond au prix de vente,\n".. + " tooltip@string@amount(+)/+ - correspond au texte de l'info-bulle.\n\n".. + "La partie optionnelle 'amount' peut être :\n".. + " un nombre - pour acheter une quantité statique,\n".. + " un signe + - pour reconstituer la pile partielle existante ou acheter une nouvelle,\n".. + " les deux (par exemple, 5+) - pour acheter suffisamment d'objets pour atteindre un total spécifié (dans ce cas, 5),\n".. + " omis - par défaut à 1.\n\n".. + "Toutes les correspondances de chaînes ne sont pas sensibles à la casse et ne correspondent qu'aux symboles alphanumériques.\n".. + "La logique standard de Lua pour les branches (et/ou/parenthèses/etc.) s'applique.\n\n".. + "Exemple d'utilisation (prêtre t8 ou Shadowmourne) :\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["PERIODIC"] = "PÉRIODIQUE" +L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."] = "Maintenez cette touche enfoncée tout en utilisant la commande /addOccupation pour effacer la liste de l'NPC cible/survolé actuel." +L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."] = "Utilisez la commande de barre oblique /addOccupation tout en ciblant/survolant un NPC pour l'ajouter à la liste. Utilisez à nouveau pour faire défiler." +L["Style Filter Icons"] = "Icônes de Filtre de Style" +L["Custom icons for the style filter."] = "Icônes personnalisées pour le filtre de style." +L["Whitelist"] = "Liste blanche" +L["X Direction"] = "Direction X" +L["Y Direction"] = "Direction Y" +L["Create Icon"] = "Créer une icône" +L["Delete Icon"] = "Supprimer l'icône" +L["0 to match frame width."] = "0 pour correspondre à la largeur du cadre." +L["Remove a NPC"] = "Supprimer un PNJ" +L["Change a NPC's Occupation"] = "Changer la profession d'un PNJ" +L["...to the currently selected one."] = "...à celui actuellement sélectionné." +L["Select Occupation"] = "Sélectionner la profession" \ No newline at end of file diff --git a/Locales/koKR.lua b/Locales/koKR.lua index 39b07a4..0c9a426 100644 --- a/Locales/koKR.lua +++ b/Locales/koKR.lua @@ -2,16 +2,16 @@ local E = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, Global local L = E.Libs.ACL:NewLocale("ElvUI", "koKR") L["Hits the 'Confirm' button automatically."] = "'확인' 버튼을 자동으로 클릭합니다." -L["Picks up quest items and money automatically."] = "퀘스트 아이템과 돈을 자동으로 획득합니다." -L["Fills 'DELETE' field automatically."] = "'삭제' 필드를 자동으로 채웁니다." -L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."] = "수정자 키를 누르지 않는 한, 대화 옵션이 하나만 있을 경우 자동으로 선택합니다.\n중요한 이벤트 트리거에 주의하세요. 안전장치가 없습니다." +L["Picks up items and money automatically."] = "아이템과 돈을 자동으로 줍습니다." +L["Automatically fills the 'DELETE' field."] = "'삭제' 필드를 자동으로 채웁니다." +L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."] = "수정자 키를 누르지 않는 한, 대화 옵션이 하나만 있을 경우 자동으로 선택합니다.\n중요한 이벤트 트리거에 주의하세요. 안전장치가 없습니다." L["Accepts and turns in quests automatically while holding a modifier."] = "수정자 키를 누른 상태에서 퀘스트를 자동으로 수락하고 완료합니다." L["Loot info wiped."] = "전리품 정보가 지워졌습니다." L["/lootinfo slash command to get a quick rundown of the recent lootings.\n\nUsage: /lootinfo Apple 60\n'Apple' - item/player name \n(search @self to get player loot)\n'60' - \ntime limit (<60 seconds ago), optional,\n/lootinfo !wipe - purge loot cache."] = "/lootinfo 명령어로 최근 획득한 아이템을 빠르게 요약해줍니다.\n\n사용법: /lootinfo 사과 60\n'사과' - 아이템/플레이어 이름 \n(플레이어의 전리품을 얻으려면 @self 검색)\n'60' - \n시간 제한 (<60초 전), 선택 사항,\n/lootinfo !wipe - 전리품 캐시 삭제." -L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "일부 메시지에서 온라인 친구와 길드원의 이름에 색을 입히고 주사위 굴림을 스타일링합니다.\n이미 처리된 채팅 말풍선은 /reload 전까지 스타일이 적용되지 않습니다." +L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "일부 메시지에서 온라인 친구와 길드원의 이름에 색을 입히고 주사위 굴림을 스타일링합니다.\n이미 처리된 채팅 말풍선은 /reload 전까지 스타일이 적용되지 않습니다." L["Colors loot roll messages for you and other players."] = "당신과 다른 플레이어의 전리품 주사위 메시지에 색을 입힙니다." L["Loot rolls icon size."] = "전리품 주사위 아이콘 크기." -L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "전리품 바의 스타일을 변경합니다.\n'전리품 주사위' (일반 -> BlizzUI 개선 -> 전리품 주사위)가 활성화되어야 합니다 (이 모듈을 토글하면 자동으로 활성화됩니다)." +L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "전리품 바의 스타일을 변경합니다.\n'전리품 주사위' (일반 -> BlizzUI 개선 -> 전리품 주사위)가 활성화되어야 합니다 (이 모듈을 토글하면 자동으로 활성화됩니다)." L["Displays the name of the player pinging the minimap."] = "미니맵을 핑한 플레이어의 이름을 표시합니다." L["Displays the currently held currency amount next to the item prices."] = "아이템 가격 옆에 현재 보유 중인 화폐 금액을 표시합니다." L["Narrows down the World(..Frame)."] = "월드(..프레임)를 좁힙니다." @@ -27,7 +27,7 @@ L["Adds shadows to all of the frames.\nDoes nothing unless you replace your ElvU L["Combat state notification alerts."] = "전투 상태 알림 경고." L["Custom editbox position and size."] = "사용자 정의 편집 상자 위치 및 크기." L["Usage:".. - "\n/tnote list - returns all eixting notes".. + "\n/tnote list - returns all existing notes".. "\n/tnote wipe - clears all existing notes".. "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. "\n/tnote 1 get - same as set, returns existing notes".. @@ -68,29 +68,26 @@ L["Usage:".. "\n (1-percentage)*255, percentage*255)" L["Adds an icon next to chat hyperlinks."] = "채팅 하이퍼링크 옆에 아이콘을 추가합니다." L["A new action bar that collects usable quest items from your bag.\n\nDue to state actions limit, this module overrides bar10 created by ElvUI Extra Action Bars."] = "가방에서 사용 가능한 퀘스트 아이템을 수집하는 새로운 액션 바입니다.\n\n상태 액션 제한으로 인해 이 모듈은 ElvUI Extra Action Bars에서 생성한 bar10을 덮어씁니다." -L["Toggles the display of the actionbars backdrop."] = "액션 바 배경 표시를 전환합니다." -L["The frame won't show unless you mouse over it."] = "마우스를 올리지 않으면 프레임이 표시되지 않습니다." -L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "전역 페이드를 상속받아 마우스 오버, 대상 지정, 주시 설정, 체력 손실, 전투 진입 시 투명도를 제거합니다. 그렇지 않으면 전역 페이드 알파에 대한 일반 액션 바 설정의 투명도 레벨을 사용합니다." +L["Toggles the display of the actionbar's backdrop."] = "액션 바 배경 표시를 전환합니다." +L["The frame will not be displayed unless hovered over."] = "마우스를 올리지 않으면 프레임이 표시되지 않습니다." +L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "전역 페이드를 상속받아 마우스 오버, 대상 지정, 주시 설정, 체력 손실, 전투 진입 시 투명도를 제거합니다. 그렇지 않으면 전역 페이드 알파에 대한 일반 액션 바 설정의 투명도 레벨을 사용합니다." L["The first button anchors itself to this point on the bar."] = "첫 번째 버튼이 바의 이 지점에 고정됩니다." L["Right-click the item while holding the modifier to blacklist it. Blacklisted items will not show up on the bar.\nUse /questbarRestore to purge the blacklist."] = "수정자를 누른 상태에서 아이템을 우클릭하여 블랙리스트에 추가합니다. 블랙리스트에 있는 아이템은 바에 표시되지 않습니다.\n블랙리스트를 제거하려면 /questbarRestore를 사용하세요." -L["The amount of buttons to display."] = "표시할 버튼의 수입니다." -L["The amount of buttons to display per row."] = "행당 표시할 버튼의 수입니다." +L["The number of buttons to display."] = "표시할 버튼의 수입니다." +L["The number of buttons to display per row."] = "행당 표시할 버튼의 수입니다." L["The size of the action buttons."] = "액션 버튼의 크기입니다." -L["The spacing between buttons."] = "버튼 사이의 간격입니다." -L["The spacing between the backdrop and the buttons."] = "배경과 버튼 사이의 간격입니다." -L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."] = "배경의 높이나 너비에 이 값을 곱합니다. 배경 뒤에 여러 개의 바를 두고 싶을 때 유용합니다." -L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"] = "이것은 매크로처럼 작동하며, 다양한 상황에서 액션 바를 다르게 표시/숨길 수 있습니다.\n 예: '[combat] showhide'" -L["Adds anchoring options to movers' nudges."] = "이동기의 미세 조정에 고정 옵션을 추가합니다." -L["Mod-clicking an item suggest a skill/item to process it."] = "수정자 키를 누른 채 아이템을 클릭하면 처리할 기술/아이템을 제안합니다." -L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = +L["Spacing between the buttons."] = "버튼 사이의 간격입니다." +L["Spacing between the backdrop and the buttons."] = "배경과 버튼 사이의 간격입니다." +L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."] = "배경의 높이나 너비에 이 값을 곱합니다. 배경 뒤에 여러 개의 바를 두고 싶을 때 유용합니다." +L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"] = "이것은 매크로처럼 작동하며, 다양한 상황에서 액션 바를 다르게 표시/숨길 수 있습니다.\n 예: '[combat] showhide'" +L["Adds anchoring options to the movers' nudges."] = "이동기의 미세 조정에 고정 옵션을 추가합니다." +L["Mod-clicking an item suggests a skill/item to process it."] = "수정자 키를 누른 채 아이템을 클릭하면 처리할 기술/아이템을 제안합니다." +L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = "%s 를 누른 상태에서 스택을 왼쪽 클릭하면 두 개로 나뉩니다; 사용 가능한 복사본을 결합하려면 대신 오른쪽 클릭하세요.".. "\n\n또한 SplitStackFrame을 수정하여 화살표 대신 편집 상자를 사용합니다." L["Extends the bags functionality."] = "가방 기능을 확장합니다." -L["Handles automated repositioning of the newly received items."] = "새로 받은 아이템의 자동 재배치를 처리합니다." -L["Default method: type > inventoryslotid > ilvl > name."] = "기본 방식: 유형 > 인벤토리 슬롯 ID > 아이템 레벨 > 이름." +L["Default method: type > inventory slot ID > item level > name."] = "기본 방식: 유형 > 인벤토리 슬롯 ID > 아이템 레벨 > 이름." L["Listed ItemIDs will not get sorted."] = "나열된 아이템 ID는 정렬되지 않습니다." -L["Double-click the title text to minimize the section."] = "제목 텍스트를 더블클릭하여 섹션을 최소화합니다." -L["Minimized section's line color."] = "최소화된 섹션의 선 색상." L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"] = "예: Interface\\Icons\\INV_Misc_QuestionMark" L["Invalid condition format: "] = "잘못된 조건 형식: " L["The generated custom sorting method did not return a function."] = "생성된 사용자 정의 정렬 방식이 함수를 반환하지 않았습니다." @@ -98,26 +95,26 @@ L["The loaded custom sorting method did not return a function."] = "로드된 L["Item received: "] = "아이템 받음: " L[" added."] = " 추가됨." L[" removed."] = " 제거됨." -L["Handles automated repositioning of the newly received items.".. +L["Handles the automated repositioning of the newly received items.".. "\nSyntax: filter@value\n\n".. "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. "Look up GetItemInfo API for more info on filters. ".. "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. "Example usage (priest t8 or Shadowmourne):\n".. "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. + "The below one notifies of the newly acquired items.\n\n".. "local icon = GetContainerItemInfo(bagID, slotID)\n".. "local _, link = GetItemInfo(itemID)\n".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. @@ -126,16 +123,16 @@ L["Handles automated repositioning of the newly received items.".. "새로 받은 아이템의 자동 재배치를 처리합니다.".. "\n구문: 필터@값\n\n".. "사용 가능한 필터:\n".. - "id@숫자 - 아이템 ID와 일치,\n".. - "name@문자열 - 이름과 일치,\n".. - "subtype@문자열 - 하위 유형과 일치,\n".. - "ilvl@숫자 - 아이템 레벨과 일치,\n".. - "uselevel@숫자 - 장비 레벨과 일치,\n".. - "quality@숫자 - 품질과 일치,\n".. - "equipslot@숫자 - 인벤토리 슬롯 ID와 일치,\n".. - "maxstack@숫자 - 최대 중첩 수와 일치,\n".. - "price@숫자 - 판매 가격과 일치,\n\n".. - "tooltip@문자열 - 툴팁 텍스트와 일치,\n\n".. + " id@숫자 - 아이템 ID와 일치,\n".. + " name@문자열 - 이름과 일치,\n".. + " subtype@문자열 - 하위 유형과 일치,\n".. + " ilvl@숫자 - 아이템 레벨과 일치,\n".. + " uselevel@숫자 - 장비 레벨과 일치,\n".. + " quality@숫자 - 품질과 일치,\n".. + " equipslot@숫자 - 인벤토리 슬롯 ID와 일치,\n".. + " maxstack@숫자 - 최대 중첩 수와 일치,\n".. + " price@숫자 - 판매 가격과 일치,\n\n".. + " tooltip@문자열 - 툴팁 텍스트와 일치,\n\n".. "모든 문자열 일치는 대소문자를 구분하지 않으며 알파벳과 숫자 기호만 일치합니다. 표준 Lua 논리가 적용됩니다. ".. "필터에 대한 자세한 정보는 GetItemInfo API를 참조하세요. ".. "현지화된 유형 및 하위 유형 값을 얻으려면 GetAuctionItemClasses 및 GetAuctionItemSubClasses(경매장과 동일)를 사용하세요.\n\n".. @@ -148,6 +145,47 @@ L["Handles automated repositioning of the newly received items.".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. "print('아이템 획득: ' .. string)" +L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "구문: 필터@값\n\n".. + "사용 가능한 필터:\n".. + " id@숫자 - 아이템ID와 일치,\n".. + " name@문자열 - 이름과 일치,\n".. + " type@문자열 - 유형과 일치,\n".. + " subtype@문자열 - 하위 유형과 일치,\n".. + " ilvl@숫자 - 아이템 레벨과 일치,\n".. + " uselevel@숫자 - 장비 레벨과 일치,\n".. + " quality@숫자 - 품질과 일치,\n".. + " equipslot@숫자 - 인벤토리 슬롯ID와 일치,\n".. + " maxstack@숫자 - 최대 중첩 수와 일치,\n".. + " price@숫자 - 판매 가격과 일치,\n".. + " tooltip@문자열 - 툴팁 텍스트와 일치.\n\n".. + "모든 문자열 일치는 대소문자를 구분하지 않으며 영숫자 기호만 일치합니다.\n".. + "분기에 대한 표준 lua 로직(and/or/괄호/등)이 적용됩니다.\n\n".. + "사용 예시 (사제 t8 또는 섀도몬):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["Available Item Types"] = "사용 가능한 아이템 유형" +L["Lists all available item subtypes for each available item type."] = + "사용 가능한 각 아이템 유형에 대한 모든 하위 유형을 나열합니다." +L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."] = + "이 키를 누른 상태로 상인과 상호작용하면 자동 구매 설정에 맞는 모든 아이템을 구매합니다.\n".. + "목록 항목을 모드 클릭하면 '@수량' 규칙에 관계없이 해당 아이템 하나만 구매합니다." L["Default method: type > inventoryslotid > ilvl > name.\n\n".. "Accepts custom functions (bagID and slotID are available at the a/b.bagID/slotID).\n\n".. "function(a,b)\n".. @@ -171,7 +209,7 @@ L["Syntax:".. "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -181,13 +219,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. @@ -210,13 +248,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(플레이어가 오라를 얻거나 잃었습니다)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..'가 영향을 받았습니다!')".. @@ -224,7 +262,7 @@ L["Syntax:".. "\n\n이 모듈은 문자열을 구문 분석하므로 코드가 구문을 엄격히 따르도록 하십시오. 그렇지 않으면 작동하지 않을 수 있습니다." L["Highlights auras."] = "오라를 강조합니다." L["E.g. 42292"] = "예: 42292" -L["Aplies highlights to all auras passing the selected filter."] = "선택한 필터를 통과하는 모든 오라를 강조합니다." +L["Applies highlights to all auras passing the selected filter."] = "선택한 필터를 통과하는 모든 오라를 강조합니다." L["Priority: spell, filter, curable/stealable."] = "우선순위: 주문, 필터, 치료 가능/도둑질 가능." L["If toggled, the GLOBAL Spell or Filter entry values would be used."] = "활성화되면 전역 주문 또는 필터 값이 사용됩니다." L["Makes auras grow sideswise."] = "오라가 옆으로 성장하게 합니다." @@ -236,7 +274,15 @@ L["Right-click a player buff to cancel it."] = "플레이어의 버프를 오른 L["Disables debuffs desaturation."] = "디버프의 색상 탈색을 비활성화합니다." L["Saturated Debuffs"] = "채도가 높은 디버프" L["Confirm Rolls"] = "주사위 굴림 확인" -L["Quest Items and Money"] = "퀘스트 아이템 및 돈" +L["Auto Pickup"] = "자동 획득" +L["Swift Buy"] = "빠른 구매" +L["Buys out items automatically."] = "아이템을 자동으로 구매합니다." +L["Failsafe"] = "안전 장치" +L["Enables popup confirmation dialog."] = "팝업 확인 대화 상자를 활성화합니다." +L["Add Set"] = "세트 추가" +L["Delete Set"] = "세트 삭제" +L["Select Set"] = "세트 선택" +L["Auto Buy"] = "자동 구매" L["Fill Delete"] = "삭제 필드 채우기" L["Gossip"] = "대화" L["Accept Quest"] = "퀘스트 수락" @@ -272,7 +318,6 @@ L["Select Container Type"] = "컨테이너 유형 선택" L["Settings"] = "설정" L["Add Section"] = "섹션 추가" L["Delete Section"] = "섹션 삭제" -L["Section Length"] = "섹션 길이" L["Select Section"] = "섹션 선택" L["Section Priority"] = "섹션 우선순위" L["Section Spacing"] = "섹션 간격" @@ -280,8 +325,6 @@ L["Collection Method"] = "수집 방법" L["Sorting Method"] = "정렬 방법" L["Ignore Item (by ID)"] = "아이템 무시 (ID별)" L["Remove Ignored"] = "무시된 항목 제거" -L["Minimize"] = "최소화" -L["Line Color"] = "선 색상" L["Title"] = "제목" L["Color"] = "색상" L["Attach to Icon"] = "아이콘에 첨부" @@ -447,13 +490,10 @@ L["Add Texture Path"] = "텍스처 경로 추가" L["Remove Selected Texture"] = "선택한 텍스처 제거" L["Titles"] = "칭호" L["Reaction Color"] = "반응 색상" -L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"] = - "/addOccupation 명령을 사용하여 현재 대상/마우스오버 직업 목록을 지우려면 이것을 누르고 있으세요.\n수정자+키 바인딩을 해제하는 것을 잊지 마세요!" L["Color based on reaction type."] = "반응 유형에 따른 색상." L["Nameplates"] = "이름표" L["Unitframes"] = "유닛프레임" -L["An icon similar to the minimap search.\n\nTooltip scanning, might not be precise.\n\nFor consistency reasons, no keywards are added by defult, use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."] = - "미니맵 검색과 유사한 아이콘입니다.\n\n툴팁 스캔, 정확하지 않을 수 있습니다.\n\n일관성을 위해 기본적으로 키워드가 추가되지 않습니다. /addOccupation 명령어를 사용하여 적절한 키워드를 직접 표시하세요 (고유한 직업 텍스트마다 한 번만 수행하면 됩니다)." +L["An icon similar to the minimap search."] = "미니맵 검색과 유사한 아이콘입니다." L["Displays player guild text."] = "플레이어의 길드 텍스트를 표시합니다." L["Displays NPC occupation text."] = "NPC의 직업 텍스트를 표시합니다." L["Strata"] = "계층" @@ -476,40 +516,6 @@ L["Unmark all plates."] = "모든 이름표의 표시를 해제합니다." L["Usage: '/qmark' macro bound to a key of your choice.\n\nDon't forget to also unbind your modifier keybinds!"] = "사용법: '/qmark' 매크로를 원하는 키에 바인딩하세요.\n\n수정자 키 바인딩도 해제하는 것을 잊지 마세요!" L["Use Backdrop"] = "배경 사용" -L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."] = - "사용 방법:\n%%d=%%s\n\n%%d - 아래 목록에서 인덱스\n%%s - 찾을 키워드\n\n아이콘 인덱스:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\n또한 '/addOccupation %%d' 명령어로도 사용 가능하며, 여기서 %%d는 선택적 아이콘 인덱스입니다. ".. - "인덱스가 제공되지 않으면 이 명령어는 사용 가능한 모든 아이콘을 순환합니다. TARGET 또는 MOUSEOVER에서 작동하며 후자를 우선합니다." L["Linked Style Filter Triggers"] = "연결된 스타일 필터 트리거" L["Select Link"] = "링크 선택" L["New Link"] = "새 링크" @@ -614,7 +620,7 @@ L["Disable Event"] = "이벤트 비활성화" L["School"] = "계열" L["Use School Colors"] = "계열 색상 사용" L["Colors"] = "색상" -L["Colors (School)"] = "색상 (계열)" +L["Color (School)"] = "색상 (계열)" L["Animation Type"] = "애니메이션 유형" L["Custom Animation"] = "사용자 정의 애니메이션" L["Flag Settings"] = "플래그 설정" @@ -700,7 +706,7 @@ L["Rare Elite"] = "희귀 정예" L["Class Spec Icons"] = "클래스 전문화 아이콘" L["Classification Textures"] = "분류 텍스처" L["Use Nameplates' Icons"] = "이름표 아이콘 사용" -L["Color enemy npc icon based on the unit type."] = "유닛 유형에 따라 적 NPC 아이콘 색상 지정." +L["Color enemy NPC icon based on the unit type."] = "유닛 유형에 따라 적 NPC 아이콘 색상 지정." L["Strata and Level"] = "계층 및 레벨" L["Warrior"] = "전사" L["Warlock"] = "흑마법사" @@ -772,7 +778,6 @@ L["On meeting multiple conditions, colors from the tab with the highest priority L["Copy Tab"] = "탭 복사" L["Select a tab to copy its settings onto the current tab."] = "현재 탭에 설정을 복사할 탭을 선택하세요." L["Flash"] = "플래시" -L["Toggle color flash for the current tab."] = "현재 탭의 색상 플래시를 토글합니다." L["Speed"] = "속도" L["Glow"] = "발광" L["Determines which glow to apply when statusbars are not detached from frame."] = "상태 바가 프레임에서 분리되지 않았을 때 적용할 발광을 결정합니다." @@ -789,7 +794,7 @@ L["Disabled unless classbar is enabled."] = "클래스바가 활성화되지 않 L["InfoPanel Color"] = "정보 패널 색상" L["Disabled unless infopanel is enabled."] = "정보 패널이 활성화되지 않으면 비활성화됩니다." L["ClassBar Adapt To"] = "클래스바 적응" -L["Copies color of the selected bar."] = "선택한 바의 색상을 복사합니다." +L["Copies the color of the selected bar."] = "선택한 바의 색상을 복사합니다." L["InfoPanel Adapt To"] = "정보 패널 적응" L["Override Mode"] = "오버라이드 모드" L["'None' - threat borders highlight will be prioritized over this one".. @@ -807,33 +812,42 @@ L["Handle only player combat log events."] = "플레이어 전투 로그 이벤 L["Rotate Icon"] = "아이콘 회전" L["Usage example:".. "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/5]@@ - 해당 탭(위 예시에서: 'player' - 대상 유닛; 'Power' - 대상 상태 바; '3' - 대상 탭)이 활성화되어 있는지 여부에 따라 true/false를 반환합니다 (동일한 유닛/그룹 언급은 비활성화됨; 재귀적이지 않음)".. + "\n local r, g, b = ElvUF_Target.Health:GetStatusBarColor()".. + "\n return true, {mR = r, mG = g, mB = b}".. + "\nelseif UnitIsUnit(unit, 'target') then".. + "\n return true".. + "\nend".. + "\n\n@@[raid, Health, 2, >5]@@ - 해당 탭 (위 예시에서: 'player' - 대상 유닛; 'Power' - 대상 상태 바; '3' - 대상 탭) ".. + "이 활성화되어 있는지 여부에 따라 true/false를 반환합니다".. "\n(>/>=/<=/=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = + "자동 아이템 배치 처리.\n".. + "문법: filter@value\n\n".. + "사용 가능한 필터:\n".. + " id@number - itemID 일치,\n".. + " name@string - 이름 일치,\n".. + " type@string - 유형 일치,\n".. + " subtype@string - 하위 유형 일치,\n".. + " ilvl@number - 아이템 레벨 일치,\n".. + " uselevel@number - 착용 레벨 일치,\n".. + " quality@number - 품질 일치,\n".. + " equipslot@number - 인벤토리 슬롯 ID 일치,\n".. + " maxstack@number - 최대 스택 크기 일치,\n".. + " price@number - 판매 가격 일치,\n".. + " tooltip@string - 툴팁 텍스트 일치,\n".. + " set@setName - 장비 세트 아이템 일치.\n\n".. + "모든 문자열 일치는 대소문자를 구분하지 않으며, 영숫자 기호만 일치합니다.\n".. + "표준 Lua 논리 연산자(and/or/괄호 등) 사용 가능합니다.\n\n".. + "사용 예시 (사제 t8 또는 섀도우모른):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "사용자 지정 함수 허용 (bagID, slotID, itemID 노출됨)\n".. + "아래 함수는 새로 획득한 아이템을 알립니다.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('아이템 획득: ' .. string)" +L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "문법: filter@value@amount\n\n".. + "사용 가능한 필터:\n".. + " id@number@amount(+)/+ - itemID 일치,\n".. + " name@string@amount(+)/+ - 이름 일치,\n".. + " type@string@amount(+)/+ - 유형 일치,\n".. + " subtype@string@amount(+)/+ - 하위 유형 일치,\n".. + " ilvl@number@amount(+)/+ - 아이템 레벨 일치,\n".. + " uselevel@number@amount(+)/+ - 착용 레벨 일치,\n".. + " quality@number@amount(+)/+ - 품질 일치,\n".. + " equipslot@number@amount(+)/+ - 인벤토리 슬롯 ID 일치,\n".. + " maxstack@number@amount(+)/+ - 최대 스택 크기 일치,\n".. + " price@number@amount(+)/+ - 판매 가격 일치,\n".. + " tooltip@string@amount(+)/+ - 툴팁 텍스트 일치.\n\n".. + "선택적 'amount' 부분:\n".. + " 숫자 - 고정된 수량 구매,\n".. + " + 기호 - 기존 스택을 보충하거나 새로운 스택 구매,\n".. + " 둘 다 (예: 5+) - 지정된 총 수량(이 경우 5)에 도달하도록 구매,\n".. + " 생략 - 기본값은 1.\n\n".. + "모든 문자열 일치는 대소문자를 구분하지 않으며, 영숫자 기호만 일치합니다.\n".. + "표준 Lua 논리 연산자(and/or/괄호 등) 사용 가능합니다.\n\n".. + "사용 예시 (사제 t8 또는 섀도우모른):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["PERIODIC"] = "주기적" +L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."] = "/addOccupation 명령어를 사용할 때 이 키를 누르고 있으면 현재 대상/마우스오버 NPC 목록이 삭제됩니다." +L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."] = "NPC를 대상으로 하거나 마우스오버 중일 때 /addOccupation 명령어를 사용하여 목록에 추가하세요. 다시 사용하면 순환합니다." +L["Style Filter Icons"] = "스타일 필터 아이콘" +L["Custom icons for the style filter."] = "스타일 필터용 사용자 정의 아이콘." +L["Whitelist"] = "허용 목록" +L["X Direction"] = "X 방향" +L["Y Direction"] = "Y 방향" +L["Create Icon"] = "아이콘 만들기" +L["Delete Icon"] = "아이콘 삭제" +L["0 to match frame width."] = "프레임 너비에 맞추기 위한 0." +L["Remove a NPC"] = "NPC 제거" +L["Change a NPC's Occupation"] = "NPC의 직업 변경" +L["...to the currently selected one."] = "...현재 선택된 것으로." +L["Select Occupation"] = "직업 선택" \ No newline at end of file diff --git a/Locales/ptBR.lua b/Locales/ptBR.lua index ee5c596..2851323 100644 --- a/Locales/ptBR.lua +++ b/Locales/ptBR.lua @@ -2,16 +2,16 @@ local E = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, Global local L = E.Libs.ACL:NewLocale("ElvUI", "ptBR") L["Hits the 'Confirm' button automatically."] = "Clica automaticamente no botão 'Confirmar'." -L["Picks up quest items and money automatically."] = "Recolhe automaticamente itens e dinheiro de missões." -L["Fills 'DELETE' field automatically."] = "Preenche automaticamente o campo 'EXCLUIR'." -L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."] = "Seleciona a primeira opção de diálogo se for a única disponível, a menos que uma tecla modificadora esteja pressionada.\nCuidado com gatilhos de eventos importantes, não há mecanismo de segurança." +L["Picks up items and money automatically."] = "Coleta itens e dinheiro automaticamente." +L["Automatically fills the 'DELETE' field."] = "Preenche automaticamente o campo 'EXCLUIR'." +L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."] = "Seleciona a primeira opção de diálogo se for a única disponível, a menos que uma tecla modificadora esteja pressionada.\nCuidado com gatilhos de eventos importantes, não há mecanismo de segurança." L["Accepts and turns in quests automatically while holding a modifier."] = "Aceita e entrega missões automaticamente enquanto uma tecla modificadora está pressionada." L["Loot info wiped."] = "Informações de saque apagadas." L["/lootinfo slash command to get a quick rundown of the recent lootings.\n\nUsage: /lootinfo Apple 60\n'Apple' - item/player name \n(search @self to get player loot)\n'60' - \ntime limit (<60 seconds ago), optional,\n/lootinfo !wipe - purge loot cache."] = "Comando /lootinfo para obter um resumo rápido dos saques recentes.\n\nUso: /lootinfo Maçã 60\n'Maçã' - nome do item/jogador \n(pesquise @self para obter o saque do jogador)\n'60' - \nlimite de tempo (<60 segundos atrás), opcional,\n/lootinfo !wipe - limpar cache de saque." -L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Colore os nomes de amigos online e membros da guilda em algumas mensagens e estiliza as rolagens.\nBalões de chat já processados não serão estilizados antes de você usar /reload." +L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Colore os nomes de amigos online e membros da guilda em algumas mensagens e estiliza as rolagens.\nBalões de chat já processados não serão estilizados antes de você usar /reload." L["Colors loot roll messages for you and other players."] = "Colore as mensagens de rolagem de saque para você e outros jogadores." L["Loot rolls icon size."] = "Tamanho do ícone das rolagens de saque." -L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Reestiliza as barras de saque.\nRequer que 'Rolagem de Saque' (Geral -> Melhorias BlizzUI -> Rolagem de Saque) esteja ativado (alternar este módulo o ativa automaticamente)." +L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Reestiliza as barras de saque.\nRequer que 'Rolagem de Saque' (Geral -> Melhorias BlizzUI -> Rolagem de Saque) esteja ativado (alternar este módulo o ativa automaticamente)." L["Displays the name of the player pinging the minimap."] = "Exibe o nome do jogador que está pingando o minimapa." L["Displays the currently held currency amount next to the item prices."] = "Exibe a quantidade de moeda atualmente possuída ao lado dos preços dos itens." L["Narrows down the World(..Frame)."] = "Reduz o World(..Frame)." @@ -27,7 +27,7 @@ L["Adds shadows to all of the frames.\nDoes nothing unless you replace your ElvU L["Combat state notification alerts."] = "Alertas de notificação de estado de combate." L["Custom editbox position and size."] = "Posição e tamanho personalizados da caixa de edição." L["Usage:".. - "\n/tnote list - returns all eixting notes".. + "\n/tnote list - returns all existing notes".. "\n/tnote wipe - clears all existing notes".. "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. "\n/tnote 1 get - same as set, returns existing notes".. @@ -68,29 +68,26 @@ L["Usage:".. "\n (1-percentage)*255, percentage*255)" L["Adds an icon next to chat hyperlinks."] = "Adiciona um ícone ao lado dos hyperlinks do chat." L["A new action bar that collects usable quest items from your bag.\n\nDue to state actions limit, this module overrides bar10 created by ElvUI Extra Action Bars."] = "Uma nova barra de ação que coleta itens de missão utilizáveis da sua bolsa.\n\nDevido ao limite de ações de estado, este módulo substitui a barra10 criada pelo ElvUI Extra Action Bars." -L["Toggles the display of the actionbars backdrop."] = "Alterna a exibição do plano de fundo das barras de ação." -L["The frame won't show unless you mouse over it."] = "O quadro não será exibido a menos que você passe o mouse sobre ele." -L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Herda o esmaecimento global, passar o mouse, selecionar alvo, definir foco, perder saúde, entrar em combate removerá a transparência. Caso contrário, usará o nível de transparência nas configurações gerais da barra de ação para o alfa de esmaecimento global." +L["Toggles the display of the actionbar's backdrop."] = "Alterna a exibição do plano de fundo das barras de ação." +L["The frame will not be displayed unless hovered over."] = "O quadro não será exibido a menos que você passe o mouse sobre ele." +L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Herda o esmaecimento global, passar o mouse, selecionar alvo, definir foco, perder saúde, entrar em combate removerá a transparência. Caso contrário, usará o nível de transparência nas configurações gerais da barra de ação para o alfa de esmaecimento global." L["The first button anchors itself to this point on the bar."] = "O primeiro botão se ancora a este ponto na barra." L["Right-click the item while holding the modifier to blacklist it. Blacklisted items will not show up on the bar.\nUse /questbarRestore to purge the blacklist."] = "Clique com o botão direito no item enquanto segura o modificador para colocá-lo na lista negra. Itens na lista negra não aparecerão na barra.\nUse /questbarRestore para limpar a lista negra." -L["The amount of buttons to display."] = "A quantidade de botões a serem exibidos." -L["The amount of buttons to display per row."] = "A quantidade de botões a serem exibidos por linha." +L["The number of buttons to display."] = "A quantidade de botões a serem exibidos." +L["The number of buttons to display per row."] = "A quantidade de botões a serem exibidos por linha." L["The size of the action buttons."] = "O tamanho dos botões de ação." -L["The spacing between buttons."] = "O espaçamento entre os botões." -L["The spacing between the backdrop and the buttons."] = "O espaçamento entre o plano de fundo e os botões." -L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."] = "Multiplica a altura ou largura do plano de fundo por este valor. Isso é útil se você deseja ter mais de uma barra atrás de um plano de fundo." -L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"] = "Isso funciona como uma macro, você pode executar diferentes situações para fazer a barra de ação aparecer/desaparecer de maneira diferente.\n Exemplo: '[combat] showhide'" -L["Adds anchoring options to movers' nudges."] = "Adiciona opções de ancoragem aos empurrões dos movimentadores." -L["Mod-clicking an item suggest a skill/item to process it."] = "Clicar com o modificador em um item sugere uma habilidade/item para processá-lo." -L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = +L["Spacing between the buttons."] = "O espaçamento entre os botões." +L["Spacing between the backdrop and the buttons."] = "O espaçamento entre o plano de fundo e os botões." +L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."] = "Multiplica a altura ou largura do plano de fundo por este valor. Isso é útil se você deseja ter mais de uma barra atrás de um plano de fundo." +L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"] = "Isso funciona como uma macro, você pode executar diferentes situações para fazer a barra de ação aparecer/desaparecer de maneira diferente.\n Exemplo: '[combat] showhide'" +L["Adds anchoring options to the movers' nudges."] = "Adiciona opções de ancoragem aos empurrões dos movimentadores." +L["Mod-clicking an item suggests a skill/item to process it."] = "Clicar com o modificador em um item sugere uma habilidade/item para processá-lo." +L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = "Segurando %s enquanto clica com o botão esquerdo em uma pilha a divide em duas; para combinar cópias disponíveis, clique com o botão direito.".. "\n\nTambém modifica o SplitStackFrame para usar caixa de edição em vez de setas." L["Extends the bags functionality."] = "Estende a funcionalidade das bolsas." -L["Handles automated repositioning of the newly received items."] = "Lida com o reposicionamento automatizado dos itens recém-recebidos." -L["Default method: type > inventoryslotid > ilvl > name."] = "Método padrão: tipo > id do slot de inventário > nível do item > nome." +L["Default method: type > inventory slot ID > item level > name."] = "Método padrão: tipo > id do slot de inventário > nível do item > nome." L["Listed ItemIDs will not get sorted."] = "IDs de itens listados não serão ordenados." -L["Double-click the title text to minimize the section."] = "Clique duas vezes no texto do título para minimizar a seção." -L["Minimized section's line color."] = "Cor da linha da seção minimizada." L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"] = "Ex: Interface\\Icons\\INV_Misc_QuestionMark" L["Invalid condition format: "] = "Formato de condição inválido: " L["The generated custom sorting method did not return a function."] = "O método de ordenação personalizado gerado não retornou uma função." @@ -98,44 +95,44 @@ L["The loaded custom sorting method did not return a function."] = "O método de L["Item received: "] = "Item recebido: " L[" added."] = " adicionado." L[" removed."] = " removido." -L["Handles automated repositioning of the newly received items.".. - "\nSyntax: filter@value\n\n".. - "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. - "Look up GetItemInfo API for more info on filters. ".. - "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. - "Example usage (priest t8 or Shadowmourne):\n".. - "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. - "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. - "local icon = GetContainerItemInfo(bagID, slotID)\n".. - "local _, link = GetItemInfo(itemID)\n".. - "icon = gsub(icon, '\\124', '\\124\\124')\n".. - "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. - "print('Item received: ' .. string)"] = +L["Handles the automated repositioning of the newly received items.".. + "\nSyntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. + "Look up GetItemInfo API for more info on filters. ".. + "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = "Lida com o reposicionamento automático dos itens recém-recebidos.".. "\nSintaxe: filtro@valor\n\n".. "Filtros disponíveis:\n".. - "id@número - corresponde ao ID do item,\n".. - "name@string - corresponde ao nome,\n".. - "subtype@string - corresponde ao subtipo,\n".. - "ilvl@número - corresponde ao nível do item,\n".. - "uselevel@número - corresponde ao nível de equipamento,\n".. - "quality@número - corresponde à qualidade,\n".. - "equipslot@número - corresponde ao ID do slot de inventário,\n".. - "maxstack@número - corresponde ao limite de pilha,\n".. - "price@número - corresponde ao preço de venda,\n\n".. - "tooltip@string - corresponde ao texto da dica,\n\n".. + " id@número - corresponde ao ID do item,\n".. + " name@string - corresponde ao nome,\n".. + " subtype@string - corresponde ao subtipo,\n".. + " ilvl@número - corresponde ao nível do item,\n".. + " uselevel@número - corresponde ao nível de equipamento,\n".. + " quality@número - corresponde à qualidade,\n".. + " equipslot@número - corresponde ao ID do slot de inventário,\n".. + " maxstack@número - corresponde ao limite de pilha,\n".. + " price@número - corresponde ao preço de venda,\n\n".. + " tooltip@string - corresponde ao texto da dica,\n\n".. "Todas as correspondências de string não diferenciam maiúsculas de minúsculas e correspondem apenas aos símbolos alfanuméricos. A lógica padrão de Lua se aplica. ".. "Consulte a API GetItemInfo para mais informações sobre filtros. ".. "Use GetAuctionItemClasses e GetAuctionItemSubClasses (igual à Casa de Leilões) para obter os valores localizados de tipos e subtipos.\n\n".. @@ -148,6 +145,47 @@ L["Handles automated repositioning of the newly received items.".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. "print('Item recebido: ' .. string)" +L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Sintaxe: filtro@valor\n\n".. + "Filtros disponíveis:\n".. + " id@número - corresponde ao ID do item,\n".. + " name@texto - corresponde ao nome,\n".. + " type@texto - corresponde ao tipo,\n".. + " subtype@texto - corresponde ao subtipo,\n".. + " ilvl@número - corresponde ao nível do item,\n".. + " uselevel@número - corresponde ao nível de equipamento,\n".. + " quality@número - corresponde à qualidade,\n".. + " equipslot@número - corresponde ao ID do slot do inventário,\n".. + " maxstack@número - corresponde ao limite de pilha,\n".. + " price@número - corresponde ao preço de venda,\n".. + " tooltip@texto - corresponde ao texto da dica.\n\n".. + "Todas as correspondências de texto não diferenciam maiúsculas de minúsculas e correspondem apenas a símbolos alfanuméricos.\n".. + "A lógica lua padrão para ramificação (e/ou/parênteses/etc.) se aplica.\n\n".. + "Exemplo de uso (sacerdote t8 ou Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["Available Item Types"] = "Tipos de Item Disponíveis" +L["Lists all available item subtypes for each available item type."] = + "Lista todos os subtipos de item disponíveis para cada tipo de item disponível." +L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."] = + "Segurar esta tecla enquanto interage com um comerciante compra todos os itens que atendem ao método de Compra Automática.\n".. + "Mod-clique na entrada da lista de compra para adquirir apenas um dos itens, independentemente da regra '@quantidade'." L["Default method: type > inventoryslotid > ilvl > name.\n\n".. "Accepts custom functions (bagID and slotID are available at the a/b.bagID/slotID).\n\n".. "function(a,b)\n".. @@ -171,7 +209,7 @@ L["Syntax:".. "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -181,13 +219,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. @@ -210,13 +248,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(jogador ganhou/perdeu uma aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' está afetado!')".. @@ -224,7 +262,7 @@ L["Syntax:".. "\n\nEste módulo analisa strings, então tente fazer com que seu código siga a sintaxe estritamente, caso contrário, pode não funcionar." L["Highlights auras."] = "Destaca auras." L["E.g. 42292"] = "Ex.: 42292" -L["Aplies highlights to all auras passing the selected filter."] = "Destaca todas as auras que passam pelo filtro selecionado." +L["Applies highlights to all auras passing the selected filter."] = "Destaca todas as auras que passam pelo filtro selecionado." L["Priority: spell, filter, curable/stealable."] = "Prioridade: feitiço, filtro, curável/roubável." L["If toggled, the GLOBAL Spell or Filter entry values would be used."] = "Se ativado, serão usados os valores de Feitiço ou Filtro GLOBAL." L["Makes auras grow sideswise."] = "Faz com que as auras cresçam lateralmente." @@ -236,7 +274,15 @@ L["Right-click a player buff to cancel it."] = "Clique com o botão direito em u L["Disables debuffs desaturation."] = "Desativa a dessaturação de debuffs." L["Saturated Debuffs"] = "Debuffs Saturados" L["Confirm Rolls"] = "Confirmar rolagens" -L["Quest Items and Money"] = "Itens de missão e dinheiro" +L["Auto Pickup"] = "Coleta automática" +L["Swift Buy"] = "Compra rápida" +L["Buys out items automatically."] = "Compra itens automaticamente." +L["Failsafe"] = "Sistema de segurança" +L["Enables popup confirmation dialog."] = "Ativa o diálogo de confirmação." +L["Add Set"] = "Adicionar conjunto" +L["Delete Set"] = "Excluir conjunto" +L["Select Set"] = "Selecionar conjunto" +L["Auto Buy"] = "Compra automática" L["Fill Delete"] = "Preencher exclusão" L["Gossip"] = "Diálogo" L["Accept Quest"] = "Aceitar missão" @@ -272,7 +318,6 @@ L["Select Container Type"] = "Selecionar tipo de contêiner" L["Settings"] = "Configurações" L["Add Section"] = "Adicionar seção" L["Delete Section"] = "Excluir seção" -L["Section Length"] = "Comprimento da seção" L["Select Section"] = "Selecionar seção" L["Section Priority"] = "Prioridade da seção" L["Section Spacing"] = "Espaçamento da seção" @@ -280,8 +325,6 @@ L["Collection Method"] = "Método de coleta" L["Sorting Method"] = "Método de ordenação" L["Ignore Item (by ID)"] = "Ignorar item (por ID)" L["Remove Ignored"] = "Remover ignorados" -L["Minimize"] = "Minimizar" -L["Line Color"] = "Cor da linha" L["Title"] = "Título" L["Color"] = "Cor" L["Attach to Icon"] = "Anexar ao ícone" @@ -447,13 +490,10 @@ L["Add Texture Path"] = "Adicionar Caminho de Textura" L["Remove Selected Texture"] = "Remover Textura Selecionada" L["Titles"] = "Títulos" L["Reaction Color"] = "Cor de Reação" -L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"] = - "Segure isso enquanto usa o comando /addOccupation para limpar a lista da ocupação atual do alvo/mouseover.\nNão se esqueça de desvincular a combinação de modificador+tecla!" L["Color based on reaction type."] = "Cor baseada no tipo de reação." L["Nameplates"] = "Placas de identificação" L["Unitframes"] = "Quadros de unidade" -L["An icon similar to the minimap search.\n\nTooltip scanning, might not be precise.\n\nFor consistency reasons, no keywards are added by defult, use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."] = - "Um ícone semelhante à busca do minimapa.\n\nVarredura de dicas, pode não ser precisa.\n\nPor motivos de consistência, nenhuma palavra-chave é adicionada por padrão, use o comando /addOccupation para marcar as apropriadas você mesmo (só precisa fazer isso uma vez por texto de ocupação único)." +L["An icon similar to the minimap search."] = "Um ícone semelhante à busca do minimapa." L["Displays player guild text."] = "Exibe o texto da guilda do jogador." L["Displays NPC occupation text."] = "Exibe o texto de ocupação do PNJ." L["Strata"] = "Camada" @@ -476,40 +516,6 @@ L["Unmark all plates."] = "Desmarca todas as placas de identificação." L["Usage: '/qmark' macro bound to a key of your choice.\n\nDon't forget to also unbind your modifier keybinds!"] = "Uso: macro '/qmark' vinculada a uma tecla de sua escolha.\n\nNão se esqueça de desvincular também suas teclas de modificador!" L["Use Backdrop"] = "Usar plano de fundo" -L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."] = - "Uso:\n%%d=%%s\n\n%%d - índice da lista abaixo\n%%s - palavras-chave para procurar\n\nÍndices dos ícones:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nTambém disponível como um comando de barra '/addOccupation %%d', onde %%d é um índice de ícone opcional. ".. - "Se nenhum índice for fornecido, este comando irá alternar entre todos os ícones disponíveis. Funciona em TARGET ou MOUSEOVER, priorizando o último." L["Linked Style Filter Triggers"] = "Gatilhos de Filtro de Estilo Vinculado" L["Select Link"] = "Selecionar Link" L["New Link"] = "Novo Link" @@ -614,7 +620,7 @@ L["Disable Event"] = "Desativar Evento" L["School"] = "Escola" L["Use School Colors"] = "Usar Cores da Escola" L["Colors"] = "Cores" -L["Colors (School)"] = "Cores (Escola)" +L["Color (School)"] = "Cor (Escola)" L["Animation Type"] = "Tipo de Animação" L["Custom Animation"] = "Animação Personalizada" L["Flag Settings"] = "Configurações de Bandeira" @@ -700,7 +706,7 @@ L["Rare Elite"] = "Elite Raro" L["Class Spec Icons"] = "Ícones de Especialização de Classe" L["Classification Textures"] = "Texturas de Classificação" L["Use Nameplates' Icons"] = "Usar Ícones das Placas de Nome" -L["Color enemy npc icon based on the unit type."] = "Colorir ícone de NPC inimigo com base no tipo de unidade." +L["Color enemy NPC icon based on the unit type."] = "Colorir ícone de NPC inimigo com base no tipo de unidade." L["Strata and Level"] = "Camada e Nível" L["Warrior"] = "Guerreiro" L["Warlock"] = "Bruxo" @@ -772,7 +778,6 @@ L["On meeting multiple conditions, colors from the tab with the highest priority L["Copy Tab"] = "Copiar Aba" L["Select a tab to copy its settings onto the current tab."] = "Selecione uma aba para copiar suas configurações para a aba atual." L["Flash"] = "Piscar" -L["Toggle color flash for the current tab."] = "Alterna o piscar de cor para a aba atual." L["Speed"] = "Velocidade" L["Glow"] = "Brilho" L["Determines which glow to apply when statusbars are not detached from frame."] = "Determina qual brilho aplicar quando as barras de status não estão desanexadas do quadro." @@ -789,7 +794,7 @@ L["Disabled unless classbar is enabled."] = "Desativado a menos que a barra de c L["InfoPanel Color"] = "Cor do Painel de Informações" L["Disabled unless infopanel is enabled."] = "Desativado a menos que o painel de informações esteja ativado." L["ClassBar Adapt To"] = "Adaptar Barra de Classe Para" -L["Copies color of the selected bar."] = "Copia a cor da barra selecionada." +L["Copies the color of the selected bar."] = "Copia a cor da barra selecionada." L["InfoPanel Adapt To"] = "Adaptar Painel de Informações Para" L["Override Mode"] = "Modo de Substituição" L["'None' - threat borders highlight will be prioritized over this one".. "\n'Threat' - this highlight will be prioritized."] = "'Nenhum' - o destaque das bordas de ameaça terá prioridade sobre este".. "\n'Ameaça' - este destaque terá prioridade." @@ -804,33 +809,43 @@ L["Handle only player combat log events."] = "Lidar apenas com eventos do regist L["Rotate Icon"] = "Girar ícone" L["Usage example:".. "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/5]@@ - retorna verdadeiro/falso com base em se a aba em questão (no exemplo acima: 'player' - unidade alvo; 'Power' - barra de status alvo; '3' - aba alvo) está ativa ou não (mencionar a mesma unidade/grupo está desativado; não é recursivo)".. - "\n(>/>=/<=/5]@@ - retorna verdadeiro/falso com base em se a aba em questão ".. + "(no exemplo acima: 'player' - unidade alvo; 'Power' - barra de status alvo; '3' - aba alvo) está ativa ou não".. + "\n(>/>=/<=/=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = + "Gerencia o posicionamento automático dos itens.\n".. + "Sintaxe: filter@value\n\n".. + "Filtros disponíveis:\n".. + " id@number - corresponde ao itemID,\n".. + " name@string - corresponde ao nome,\n".. + " type@string - corresponde ao tipo,\n".. + " subtype@string - corresponde ao subtipo,\n".. + " ilvl@number - corresponde ao ilvl,\n".. + " uselevel@number - corresponde ao nível de uso,\n".. + " quality@number - corresponde à qualidade,\n".. + " equipslot@number - corresponde ao InventorySlotID,\n".. + " maxstack@number - corresponde ao limite da pilha,\n".. + " price@number - corresponde ao preço de venda,\n".. + " tooltip@string - corresponde ao texto da dica,\n".. + " set@setName - corresponde aos itens do conjunto de equipamentos.\n\n".. + "Todas as correspondências de string não diferenciam maiúsculas de minúsculas e correspondem apenas a símbolos alfanuméricos.\n".. + "A lógica padrão do Lua para ramificação (and/or/parênteses/etc.) aplica-se.\n\n".. + "Exemplo de uso (sacerdote t8 ou Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Aceita funções personalizadas (bagID, slotID, itemID são expostos).\n".. + "O exemplo abaixo notifica sobre os itens recém-adquiridos.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item adquirido: ' .. string)" +L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Sintaxe: filter@value@amount\n\n".. + "Filtros disponíveis:\n".. + " id@number@amount(+)/+ - corresponde ao itemID,\n".. + " name@string@amount(+)/+ - corresponde ao nome,\n".. + " type@string@amount(+)/+ - corresponde ao tipo,\n".. + " subtype@string@amount(+)/+ - corresponde ao subtipo,\n".. + " ilvl@number@amount(+)/+ - corresponde ao ilvl,\n".. + " uselevel@number@amount(+)/+ - corresponde ao nível de uso,\n".. + " quality@number@amount(+)/+ - corresponde à qualidade,\n".. + " equipslot@number@amount(+)/+ - corresponde ao InventorySlotID,\n".. + " maxstack@number@amount(+)/+ - corresponde ao limite da pilha,\n".. + " price@number@amount(+)/+ - corresponde ao preço de venda,\n".. + " tooltip@string@amount(+)/+ - corresponde ao texto da dica.\n\n".. + "A parte opcional 'amount' pode ser:\n".. + " um número - para comprar uma quantidade fixa,\n".. + " um sinal de + - para reabastecer a pilha parcial existente ou comprar uma nova,\n".. + " ambos (ex.: 5+) - para comprar itens suficientes para alcançar um total especificado (neste caso, 5),\n".. + " omitido - padrão é 1.\n\n".. + "Todas as correspondências de string não diferenciam maiúsculas de minúsculas e correspondem apenas a símbolos alfanuméricos.\n".. + "A lógica padrão do Lua para ramificação (and/or/parênteses/etc.) aplica-se.\n\n".. + "Exemplo de uso (sacerdote t8 ou Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["PERIODIC"] = "PERIÓDICO" +L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."] = "Segure esta tecla enquanto usa o comando /addOccupation para limpar a lista do NPC atual (alvo/sobre o qual o mouse está)." +L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."] = "Use o comando /addOccupation enquanto estiver mirando ou passando o mouse sobre um NPC para adicioná-lo à lista. Use novamente para alternar." +L["Style Filter Icons"] = "Ícones de Filtro de Estilo" +L["Custom icons for the style filter."] = "Ícones personalizados para o filtro de estilo." +L["Whitelist"] = "Lista Branca" +L["X Direction"] = "Direção X" +L["Y Direction"] = "Direção Y" +L["Create Icon"] = "Criar ícone" +L["Delete Icon"] = "Excluir ícone" +L["0 to match frame width."] = "0 para corresponder à largura do quadro." +L["Remove a NPC"] = "Remover um NPC" +L["Change a NPC's Occupation"] = "Mudar a ocupação de um NPC" +L["...to the currently selected one."] = "...para o atualmente selecionado." +L["Select Occupation"] = "Selecionar Ocupação" \ No newline at end of file diff --git a/Locales/ruRU.lua b/Locales/ruRU.lua index 5a8bb7d..517905f 100644 --- a/Locales/ruRU.lua +++ b/Locales/ruRU.lua @@ -2,22 +2,22 @@ local E = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, Global local L = E.Libs.ACL:NewLocale("ElvUI", "ruRU") L["Hits the 'Confirm' button automatically."] = "Автоматически нажимает кнопку 'Подтвердить'." -L["Picks up quest items and money automatically."] = "Автоматически подбирает предметы заданий и деньги." -L["Fills 'DELETE' field automatically."] = "Автоматически заполняет поле 'DELETE'." -L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."] = "Выбирает первый вариант диалога, если он единственный доступный, если не удерживается модификатор.\nОсторожно с важными событиями, здесь нет механизма защиты от ошибок." +L["Picks up items and money automatically."] = "Автоматически подбирает предметы и деньги." +L["Automatically fills the 'DELETE' field."] = "Автоматически заполняет поле 'DELETE'." +L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."] = "Выбирает первый вариант диалога, если он единственный доступный, если не удерживается модификатор.\nОсторожно с важными событиями, здесь нет механизма защиты от ошибок." L["Accepts and turns in quests automatically while holding a modifier."] = "Автоматически принимает и сдает задания при удержании модификатора." L["Loot info wiped."] = "Информация о добыче очищена." L["/lootinfo slash command to get a quick rundown of the recent lootings.\n\nUsage: /lootinfo Apple 60\n'Apple' - item/player name \n(search @self to get player loot)\n'60' - \ntime limit (<60 seconds ago), optional,\n/lootinfo !wipe - purge loot cache."] = "Команда /lootinfo для получения краткого обзора недавней добычи.\n\nИспользование: /lootinfo Яблоко 60\n'Яблоко' - название предмета/имя игрока \n(используйте @self для получения добычи игрока)\n'60' - \nвременной лимит (<60 секунд назад), необязательно,\n/lootinfo !wipe - очистить кэш добычи." -L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Окрашивает имена онлайн-друзей и согильдийцев в некоторых сообщениях и стилизует броски.\nУже обработанные облачка чата не будут стилизованы до /reload." +L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "Окрашивает имена онлайн-друзей и согильдийцев в некоторых сообщениях и стилизует броски.\nУже обработанные облачка чата не будут стилизованы до /reload." L["Colors loot roll messages for you and other players."] = "Окрашивает сообщения о бросках на добычу для вас и других игроков." L["Loot rolls icon size."] = "Размер иконки бросков на добычу." -L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Изменяет стиль полос добычи.\nТребуется включение 'Броска на добычу' (Общее -> Улучшения BlizzUI -> Бросок на добычу) (включение этого модуля активирует его автоматически)." +L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "Изменяет стиль полос добычи.\nТребуется включение 'Броска на добычу' (Общее -> Улучшения BlizzUI -> Бросок на добычу) (включение этого модуля активирует его автоматически)." L["Displays the name of the player pinging the minimap."] = "Отображает имя игрока, пингующего миникарту." L["Displays the currently held currency amount next to the item prices."] = "Отображает текущее количество валюты рядом с ценами на предметы." L["Narrows down the World(..Frame)."] = "Сужает World(..Frame)." L["'Out of mana', 'Ability is not ready yet', etc."] = "'Нет маны', 'Способность еще не готова' и т.д." L["Re-enable quest updates."] = "Повторно включить обновления заданий." -L["Adds anchoring options to movers' nudges."] = "Добавляет параметры привязки к подвижкам мувера." +L["Adds anchoring options to the movers' nudges."] = "Добавляет параметры привязки к подвижкам мувера." L["255, 210, 0 - Blizzard's yellow."] = "255, 210, 0 - желтый цвет Blizzard." L["Text to display upon entering combat."] = "Текст, отображаемый при входе в бой." L["Text to display upon leaving combat."] = "Текст, отображаемый при выходе из боя." @@ -28,7 +28,7 @@ L["Adds shadows to all of the frames.\nDoes nothing unless you replace your ElvU L["Combat state notification alerts."] = "Оповещения о состоянии боя." L["Custom editbox position and size."] = "Пользовательская позиция и размер поля редактирования." L["Usage:".. - "\n/tnote list - returns all eixting notes".. + "\n/tnote list - returns all existing notes".. "\n/tnote wipe - clears all existing notes".. "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. "\n/tnote 1 get - same as set, returns existing notes".. @@ -69,29 +69,25 @@ L["Usage:".. "\n (1-percentage)*255, percentage*255)" L["Adds an icon next to chat hyperlinks."] = "Добавляет значок рядом с гиперссылками в чате." L["A new action bar that collects usable quest items from your bag.\n\nDue to state actions limit, this module overrides bar10 created by ElvUI Extra Action Bars."] = "Новая панель действий, которая собирает используемые предметы для заданий из вашей сумки.\n\nИз-за ограничения действий состояния, этот модуль переопределяет bar10, созданную ElvUI Extra Action Bars." -L["Toggles the display of the actionbars backdrop."] = "Переключает отображение фона панелей действий." -L["The frame won't show unless you mouse over it."] = "Рамка не будет показываться, пока вы не наведете на нее курсор." -L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Наследует глобальное затухание, наведение мыши, выбор цели, установка фокуса, потеря здоровья, вступление в бой уберут прозрачность. В противном случае будет использоваться уровень прозрачности в общих настройках панели действий для альфа-канала глобального затухания." +L["Toggles the display of the actionbar's backdrop."] = "Переключает отображение фона панелей действий." +L["The frame will not be displayed unless hovered over."] = "Рамка не будет показываться, пока вы не наведете на нее курсор." +L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "Наследует глобальное затухание, наведение мыши, выбор цели, установка фокуса, потеря здоровья, вступление в бой уберут прозрачность. В противном случае будет использоваться уровень прозрачности в общих настройках панели действий для альфа-канала глобального затухания." L["The first button anchors itself to this point on the bar."] = "Первая кнопка привязывается к этой точке на панели." L["Right-click the item while holding the modifier to blacklist it. Blacklisted items will not show up on the bar.\nUse /questbarRestore to purge the blacklist."] = "Щелкните правой кнопкой мыши по предмету, удерживая модификатор, чтобы добавить его в черный список. Предметы из черного списка не будут отображаться на панели.\nИспользуйте /questbarRestore для очистки черного списка." -L["The amount of buttons to display."] = "Количество отображаемых кнопок." -L["The amount of buttons to display per row."] = "Количество кнопок для отображения в ряду." +L["The number of buttons to display."] = "Количество отображаемых кнопок." +L["The number of buttons to display per row."] = "Количество кнопок для отображения в ряду." L["The size of the action buttons."] = "Размер кнопок действий." -L["The spacing between buttons."] = "Расстояние между кнопками." -L["The spacing between the backdrop and the buttons."] = "Расстояние между фоном и кнопками." -L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."] = "Умножьте высоту или ширину фона на это значение. Это полезно, если вы хотите иметь более одной панели за фоном." -L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"] = "Это работает как макрос, вы можете запускать различные ситуации, чтобы панель действий отображалась/скрывалась по-разному.\n Пример: '[combat] showhide'" -L["Adds anchoring options to movers' nudges."] = "Добавляет параметры привязки к подвижкам мувера." -L["Mod-clicking an item suggest a skill/item to process it."] = "Клик с модификатором по предмету предлагает навык/предмет для его обработки." -L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = +L["Spacing between the buttons."] = "Расстояние между кнопками." +L["Spacing between the backdrop and the buttons."] = "Расстояние между фоном и кнопками." +L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."] = "Умножьте высоту или ширину фона на это значение. Это полезно, если вы хотите иметь более одной панели за фоном." +L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"] = "Это работает как макрос, вы можете запускать различные ситуации, чтобы панель действий отображалась/скрывалась по-разному.\n Пример: '[combat] showhide'" +L["Mod-clicking an item suggests a skill/item to process it."] = "Клик с модификатором по предмету предлагает навык/предмет для его обработки." +L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = "Удерживание %s при левом клике на стопку разделяет ее на две части; для объединения доступных копий используйте правый клик.".. "\n\nТакже изменяет SplitStackFrame, используя поле ввода вместо стрелок." L["Extends the bags functionality."] = "Расширяет функциональность сумок." -L["Handles automated repositioning of the newly received items."] = "Обрабатывает автоматическое перемещение вновь полученных предметов." -L["Default method: type > inventoryslotid > ilvl > name."] = "Метод по умолчанию: тип > ID слота инвентаря > уровень предмета > название." +L["Default method: type > inventory slot ID > item level > name."] = "Метод по умолчанию: тип > ID слота инвентаря > уровень предмета > название." L["Listed ItemIDs will not get sorted."] = "Перечисленные ID предметов не будут отсортированы." -L["Double-click the title text to minimize the section."] = "Дважды щелкните текст заголовка, чтобы свернуть раздел." -L["Minimized section's line color."] = "Цвет линии свернутого раздела." L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"] = "Например, Interface\\Icons\\INV_Misc_QuestionMark" L["Invalid condition format: "] = "Неверный формат условия: " L["The generated custom sorting method did not return a function."] = "Сгенерированный пользовательский метод сортировки не вернул функцию." @@ -99,44 +95,44 @@ L["The loaded custom sorting method did not return a function."] = "Загруж L["Item received: "] = "Получен предмет: " L[" added."] = " добавлено." L[" removed."] = " удалено." -L["Handles automated repositioning of the newly received items.".. - "\nSyntax: filter@value\n\n".. - "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. - "Look up GetItemInfo API for more info on filters. ".. - "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. - "Example usage (priest t8 or Shadowmourne):\n".. - "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. - "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. - "local icon = GetContainerItemInfo(bagID, slotID)\n".. - "local _, link = GetItemInfo(itemID)\n".. - "icon = gsub(icon, '\\124', '\\124\\124')\n".. - "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. - "print('Item received: ' .. string)"] = +L["Handles the automated repositioning of the newly received items.".. + "\nSyntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. + "Look up GetItemInfo API for more info on filters. ".. + "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = "Обрабатывает автоматическое перемещение новых полученных предметов.".. "\nСинтаксис: фильтр@значение\n\n".. "Доступные фильтры:\n".. - "id@число - соответствует ID предмета,\n".. - "name@строка - соответствует названию,\n".. - "subtype@строка - соответствует подтипу,\n".. - "ilvl@число - соответствует уровню предмета,\n".. - "uselevel@число - соответствует уровню экипировки,\n".. - "quality@число - соответствует качеству,\n".. - "equipslot@число - соответствует ID слота инвентаря,\n".. - "maxstack@число - соответствует лимиту стака,\n".. - "price@число - соответствует цене продажи,\n\n".. - "tooltip@строка - соответствует тексту всплывающей подсказки,\n\n".. + " id@число - соответствует ID предмета,\n".. + " name@строка - соответствует названию,\n".. + " subtype@строка - соответствует подтипу,\n".. + " ilvl@число - соответствует уровню предмета,\n".. + " uselevel@число - соответствует уровню экипировки,\n".. + " quality@число - соответствует качеству,\n".. + " equipslot@число - соответствует ID слота инвентаря,\n".. + " maxstack@число - соответствует лимиту стака,\n".. + " price@число - соответствует цене продажи,\n\n".. + " tooltip@строка - соответствует тексту всплывающей подсказки,\n\n".. "Все строковые совпадения не чувствительны к регистру и соответствуют только буквенно-цифровым символам. Применяется стандартная логика lua. ".. "Посмотрите API GetItemInfo для получения дополнительной информации о фильтрах. ".. "Используйте GetAuctionItemClasses и GetAuctionItemSubClasses (как в аукционном доме) для получения локализованных значений типов и подтипов.\n\n".. @@ -149,6 +145,47 @@ L["Handles automated repositioning of the newly received items.".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. "print('Получен предмет: ' .. string)" +L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Синтаксис: фильтр@значение\n\n".. + "Доступные фильтры:\n".. + " id@число - соответствует ID предмета,\n".. + " name@строка - соответствует названию,\n".. + " type@строка - соответствует типу,\n".. + " subtype@строка - соответствует подтипу,\n".. + " ilvl@число - соответствует уровню предмета,\n".. + " uselevel@число - соответствует требуемому уровню,\n".. + " quality@число - соответствует качеству,\n".. + " equipslot@число - соответствует ID слота инвентаря,\n".. + " maxstack@число - соответствует пределу стопки,\n".. + " price@число - соответствует цене продажи,\n".. + " tooltip@строка - соответствует тексту подсказки.\n\n".. + "Все строковые соответствия нечувствительны к регистру и соответствуют только буквенно-цифровым символам.\n".. + "Применяется стандартная логика lua для ветвления (и/или/скобки/и т.д.).\n\n".. + "Пример использования (жрец t8 или Шадоумурн):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["Available Item Types"] = "Доступные типы предметов" +L["Lists all available item subtypes for each available item type."] = + "Показывает все доступные подтипы предметов для каждого доступного типа предметов." +L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."] = + "Удерживание этой клавиши при взаимодействии с торговцем покупает все предметы, соответствующие методу Автопокупки.\n".. + "Модифицированный клик по элементу списка покупок покупает только один предмет, независимо от правила '@количество'." L["Default method: type > inventoryslotid > ilvl > name.\n\n".. "Accepts custom functions (bagID and slotID are available at the a/b.bagID/slotID).\n\n".. "function(a,b)\n".. @@ -173,7 +210,7 @@ L["Syntax:".. "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -183,13 +220,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. @@ -212,13 +249,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(игрок получил/потерял ауру)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' подвержен воздействию!')".. @@ -226,7 +263,7 @@ L["Syntax:".. "\n\nЭтот модуль анализирует строки, поэтому постарайтесь, чтобы ваш код строго следовал синтаксису, иначе он может не работать." L["Highlights auras."] = "Подсвечивает ауры." L["E.g. 42292"] = "Например, 42292" -L["Aplies highlights to all auras passing the selected filter."] = "Подсвечивает все ауры, проходящие выбранный фильтр." +L["Applies highlights to all auras passing the selected filter."] = "Подсвечивает все ауры, проходящие выбранный фильтр." L["Priority: spell, filter, curable/stealable."] = "Приоритет: заклинание, фильтр, излечимый/воруемый." L["If toggled, the GLOBAL Spell or Filter entry values would be used."] = "Если включено, будут использоваться глобальные значения Заклинания или Фильтра." L["Makes auras grow sideswise."] = "Заставляет ауры расти в стороны." @@ -237,9 +274,16 @@ L["Click Cancel"] = "Отмена по клику" L["Right-click a player buff to cancel it."] = "Щелкните правой кнопкой мыши на бафе игрока, чтобы отменить его." L["Disables debuffs desaturation."] = "Отключает десатурацию дебафов." L["Saturated Debuffs"] = "Сатурированные Дебафы" - L["Confirm Rolls"] = "Подтверждать броски" -L["Quest Items and Money"] = "Предметы заданий и деньги" +L["Auto Pickup"] = "Автоподбор" +L["Swift Buy"] = "Быстрая покупка" +L["Buys out items automatically."] = "Автоматически выкупает предметы." +L["Failsafe"] = "Защита от сбоев" +L["Enables popup confirmation dialog."] = "Включает всплывающее окно подтверждения." +L["Add Set"] = "Добавить набор" +L["Delete Set"] = "Удалить набор" +L["Select Set"] = "Выбрать набор" +L["Auto Buy"] = "Автопокупка" L["Fill Delete"] = "Заполнить поле удаления" L["Gossip"] = "Диалог" L["Accept Quest"] = "Принять задание" @@ -275,7 +319,6 @@ L["Select Container Type"] = "Выбрать тип контейнера" L["Settings"] = "Настройки" L["Add Section"] = "Добавить раздел" L["Delete Section"] = "Удалить раздел" -L["Section Length"] = "Длина раздела" L["Select Section"] = "Выбрать раздел" L["Section Priority"] = "Приоритет раздела" L["Section Spacing"] = "Интервал между разделами" @@ -283,8 +326,6 @@ L["Collection Method"] = "Метод сбора" L["Sorting Method"] = "Метод сортировки" L["Ignore Item (by ID)"] = "Игнорировать предмет (по ID)" L["Remove Ignored"] = "Удалить игнорируемые" -L["Minimize"] = "Свернуть" -L["Line Color"] = "Цвет линии" L["Title"] = "Заголовок" L["Color"] = "Цвет" L["Attach to Icon"] = "Прикрепить к иконке" @@ -450,13 +491,10 @@ L["Add Texture Path"] = "Добавить путь текстуры" L["Remove Selected Texture"] = "Удалить выбранную текстуру" L["Titles"] = "Титулы" L["Reaction Color"] = "Цвет реакции" -L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"] = - "Удерживайте это при использовании команды /addOccupation, чтобы очистить список текущей профессии цели/наведения.\nНе забудьте отвязать комбинацию модификатор+клавиша!" L["Color based on reaction type."] = "Цвет на основе типа реакции." L["Nameplates"] = "Неймплейты" L["Unitframes"] = "Фреймы юнитов" -L["An icon similar to the minimap search.\n\nTooltip scanning, might not be precise.\n\nFor consistency reasons, no keywards are added by defult, use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."] = - "Значок, похожий на поиск на миникарте.\n\nСканирование всплывающих подсказок, может быть неточным.\n\nДля обеспечения согласованности ключевые слова по умолчанию не добавляются, используйте команду /addOccupation, чтобы самостоятельно отметить соответствующие (нужно сделать это только один раз для каждого уникального текста профессии)." +L["An icon similar to the minimap search."] = "Значок, похожий на поиск на миникарте." L["Displays player guild text."] = "Отображает текст гильдии игрока." L["Displays NPC occupation text."] = "Отображает текст профессии NPC." L["Strata"] = "Слой" @@ -479,40 +517,6 @@ L["Unmark all plates."] = "Снимает отметки со всех нейм L["Usage: '/qmark' macro bound to a key of your choice.\n\nDon't forget to also unbind your modifier keybinds!"] = "Использование: макрос '/qmark', привязанный к клавише по вашему выбору.\n\nНе забудьте также отвязать ваши модификаторы клавиш!" L["Use Backdrop"] = "Использовать фон" -L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."] = - "Использование:\n%%d=%%s\n\n%%d - индекс из списка ниже\n%%s - ключевые слова для поиска\n\nИндексы значков:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nТакже доступна команда '/addOccupation %%d', где %%d - это необязательный индекс значка. ".. - "Если индекс не указан, эта команда будет переключаться между всеми доступными значками. Работает с TARGET или MOUSEOVER, приоритет для MOUSEOVER." L["Linked Style Filter Triggers"] = "Связанные триггеры фильтра стилей" L["Select Link"] = "Выбрать ссылку" L["New Link"] = "Новая ссылка" @@ -617,7 +621,7 @@ L["Disable Event"] = "Отключить событие" L["School"] = "Школа" L["Use School Colors"] = "Использовать цвета школ" L["Colors"] = "Цвета" -L["Colors (School)"] = "Цвета (Школа)" +L["Color (School)"] = "Цвет (Школа)" L["Animation Type"] = "Тип анимации" L["Custom Animation"] = "Пользовательская анимация" L["Flag Settings"] = "Настройки флага" @@ -703,7 +707,7 @@ L["Rare Elite"] = "Редкий элитный" L["Class Spec Icons"] = "Иконки специализаций классов" L["Classification Textures"] = "Текстуры классификации" L["Use Nameplates' Icons"] = "Использовать иконки намплейтов" -L["Color enemy npc icon based on the unit type."] = "Окрашивать иконку вражеского NPC в зависимости от типа юнита." +L["Color enemy NPC icon based on the unit type."] = "Окрашивать иконку вражеского NPC в зависимости от типа юнита." L["Strata and Level"] = "Слой и уровень" L["Warrior"] = "Воин" L["Warlock"] = "Чернокнижник" @@ -775,7 +779,6 @@ L["On meeting multiple conditions, colors from the tab with the highest priority L["Copy Tab"] = "Копировать вкладку" L["Select a tab to copy its settings onto the current tab."] = "Выберите вкладку, чтобы скопировать ее настройки на текущую вкладку." L["Flash"] = "Вспышка" -L["Toggle color flash for the current tab."] = "Переключить цветовую вспышку для текущей вкладки." L["Speed"] = "Скорость" L["Glow"] = "Свечение" L["Determines which glow to apply when statusbars are not detached from frame."] = "Определяет, какое свечение применять, когда полосы состояния не отсоединены от фрейма." @@ -792,7 +795,7 @@ L["Disabled unless classbar is enabled."] = "Отключено, если пол L["InfoPanel Color"] = "Цвет инфопанели" L["Disabled unless infopanel is enabled."] = "Отключено, если инфопанель не включена." L["ClassBar Adapt To"] = "Адаптировать полосу класса к" -L["Copies color of the selected bar."] = "Копирует цвет выбранной полосы." +L["Copies the color of the selected bar."] = "Копирует цвет выбранной полосы." L["InfoPanel Adapt To"] = "Адаптировать инфопанель к" L["Override Mode"] = "Режим переопределения" L["'None' - threat borders highlight will be prioritized over this one".. "\n'Threat' - this highlight will be prioritized."] = "'Нет' - подсветка границ угрозы будет иметь приоритет над этой".. "\n'Угроза' - эта подсветка будет иметь приоритет." @@ -807,31 +810,41 @@ L["Handle only player combat log events."] = "Обрабатывать толь L["Rotate Icon"] = "Повернуть иконку" L["Usage example:".. "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/5]@@ - возвращает true/false в зависимости от того, активна ли рассматриваемая вкладка (в приведенном выше примере: 'player' - целевая единица; 'Power' - целевая строка состояния; '3' - целевая вкладка) или нет (упоминание той же единицы/группы отключено; не рекурсивно)".. - "\n(>/>=/<=/5]@@ - возвращает true/false в зависимости от того, активна ли рассматриваемая вкладка ".. + "(в приведенном выше примере: 'player' - целевая единица; 'Power' - целевая строка состояния; '3' - целевая вкладка) или нет".. + "\n(>/>=/<=/=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = + "Обрабатывает автоматическое размещение предметов.\n".. + "Синтаксис: filter@value\n\n".. + "Доступные фильтры:\n".. + " id@number - соответствует itemID,\n".. + " name@string - соответствует имени,\n".. + " type@string - соответствует типу,\n".. + " subtype@string - соответствует подтипу,\n".. + " ilvl@number - соответствует уровню предмета,\n".. + " uselevel@number - соответствует уровню использования,\n".. + " quality@number - соответствует качеству,\n".. + " equipslot@number - соответствует InventorySlotID,\n".. + " maxstack@number - соответствует максимальному количеству в стопке,\n".. + " price@number - соответствует цене продажи,\n".. + " tooltip@string - соответствует тексту подсказки,\n".. + " set@setName - соответствует предметам из набора экипировки.\n\n".. + "Все строки не чувствительны к регистру и соответствуют только алфавитно-цифровым символам.\n".. + "Применяются стандартные логические операторы Lua (and/or/скобки и т. д.).\n\n".. + "Пример использования (жрец t8 или Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Поддерживаются пользовательские функции (bagID, slotID, itemID доступны).\n".. + "Пример ниже уведомляет о новых полученных предметах.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Получен предмет: ' .. string)" +L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "Синтаксис: filter@value@amount\n\n".. + "Доступные фильтры:\n".. + " id@number@amount(+)/+ - соответствует itemID,\n".. + " name@string@amount(+)/+ - соответствует имени,\n".. + " type@string@amount(+)/+ - соответствует типу,\n".. + " subtype@string@amount(+)/+ - соответствует подтипу,\n".. + " ilvl@number@amount(+)/+ - соответствует уровню предмета,\n".. + " uselevel@number@amount(+)/+ - соответствует уровню использования,\n".. + " quality@number@amount(+)/+ - соответствует качеству,\n".. + " equipslot@number@amount(+)/+ - соответствует InventorySlotID,\n".. + " maxstack@number@amount(+)/+ - соответствует максимальному количеству в стопке,\n".. + " price@number@amount(+)/+ - соответствует цене продажи,\n".. + " tooltip@string@amount(+)/+ - соответствует тексту подсказки.\n\n".. + "Опциональная часть 'amount':\n".. + " число - покупка фиксированного количества,\n".. + " знак + - пополнение текущей частичной стопки или покупка новой,\n".. + " оба (например, 5+) - покупка достаточного количества, чтобы достичь заданного количества (в этом случае 5),\n".. + " пропущено - по умолчанию 1.\n\n".. + "Все строки не чувствительны к регистру и соответствуют только алфавитно-цифровым символам.\n".. + "Применяются стандартные логические операторы Lua (and/or/скобки и т. д.).\n\n".. + "Пример использования (жрец t8 или Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["PERIODIC"] = "ПЕРИОДИЧЕСКИ" +L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."] = "Удерживайте эту клавишу, используя команду /addOccupation, чтобы очистить список текущей цели/подсвеченного NPC." +L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."] = "Используйте команду /addOccupation, наводя курсор на NPC или выбирая его как цель, чтобы добавить в список. Повторное использование для переключения." +L["Style Filter Icons"] = "Иконки фильтра стилей" +L["Custom icons for the style filter."] = "Пользовательские иконки для фильтра стилей." +L["Whitelist"] = "Белый список" +L["X Direction"] = "X направление" +L["Y Direction"] = "Y направление" +L["Create Icon"] = "Создать значок" +L["Delete Icon"] = "Удалить значок" +L["0 to match frame width."] = "0 для соответствия ширине рамки." +L["Remove a NPC"] = "Удалить NPC" +L["Change a NPC's Occupation"] = "Изменить профессию NPC" +L["...to the currently selected one."] = "...на текущий выбранный." +L["Select Occupation"] = "Выбрать профессию" \ No newline at end of file diff --git a/Locales/zhCN.lua b/Locales/zhCN.lua index 92f526a..3e16647 100644 --- a/Locales/zhCN.lua +++ b/Locales/zhCN.lua @@ -2,16 +2,16 @@ local E = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, Global local L = E.Libs.ACL:NewLocale("ElvUI", "zhCN") L["Hits the 'Confirm' button automatically."] = "自动点击'确认'按钮。" -L["Picks up quest items and money automatically."] = "自动拾取任务物品和金钱。" -L["Fills 'DELETE' field automatically."] = "自动填写'删除'字段。" -L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."] = "如果只有一个对话选项可用,则自动选择第一个选项,除非按住修饰键。\n对于重要的事件触发要小心,没有故障保护机制。" +L["Picks up items and money automatically."] = "自动拾取物品和金钱。" +L["Automatically fills the 'DELETE' field."] = "自动填写'删除'字段。" +L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."] = "如果只有一个对话选项可用,则自动选择第一个选项,除非按住修饰键。\n对于重要的事件触发要小心,没有故障保护机制。" L["Accepts and turns in quests automatically while holding a modifier."] = "按住修饰键时自动接受和提交任务。" L["Loot info wiped."] = "拾取信息已清除。" L["/lootinfo slash command to get a quick rundown of the recent lootings.\n\nUsage: /lootinfo Apple 60\n'Apple' - item/player name \n(search @self to get player loot)\n'60' - \ntime limit (<60 seconds ago), optional,\n/lootinfo !wipe - purge loot cache."] = "/lootinfo 命令用于快速查看最近的战利品。\n\n用法: /lootinfo 苹果 60\n'苹果' - 物品/玩家名字 \n(搜索 @self 获取玩家的战利品)\n'60' - \n时间限制(<60秒前),可选,\n/lootinfo !wipe - 清除战利品缓存。" -L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "在某些消息中为在线好友和公会成员的名字着色,并为掷骰添加样式。\n已处理的聊天气泡在你使用 /reload 之前不会被重新设置样式。" +L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "在某些消息中为在线好友和公会成员的名字着色,并为掷骰添加样式。\n已处理的聊天气泡在你使用 /reload 之前不会被重新设置样式。" L["Colors loot roll messages for you and other players."] = "为你和其他玩家的拾取掷骰消息着色。" L["Loot rolls icon size."] = "拾取掷骰图标大小。" -L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "重新设置拾取条样式。\n需要启用'拾取掷骰'(常规 -> BlizzUI改进 -> 拾取掷骰)(切换此模块会自动启用它)。" +L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "重新设置拾取条样式。\n需要启用'拾取掷骰'(常规 -> BlizzUI改进 -> 拾取掷骰)(切换此模块会自动启用它)。" L["Displays the name of the player pinging the minimap."] = "显示在小地图上发出标记的玩家名称。" L["Displays the currently held currency amount next to the item prices."] = "在物品价格旁显示当前持有的货币数量。" L["Narrows down the World(..Frame)."] = "缩小World(..Frame)。" @@ -28,7 +28,7 @@ L["Adds shadows to all of the frames.\nDoes nothing unless you replace your ElvU L["Combat state notification alerts."] = "战斗状态通知警报。" L["Custom editbox position and size."] = "自定义编辑框位置和大小。" L["Usage:".. - "\n/tnote list - returns all eixting notes".. + "\n/tnote list - returns all existing notes".. "\n/tnote wipe - clears all existing notes".. "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. "\n/tnote 1 get - same as set, returns existing notes".. @@ -69,28 +69,25 @@ L["Usage:".. "\n (1-percentage)*255, percentage*255)" L["Adds an icon next to chat hyperlinks."] = "在聊天超链接旁添加一个图标。" L["A new action bar that collects usable quest items from your bag.\n\nDue to state actions limit, this module overrides bar10 created by ElvUI Extra Action Bars."] = "一个新的动作条,用于收集背包中可用的任务物品。\n\n由于状态动作限制,该模块会覆盖ElvUI额外动作条创建的bar10。" -L["Toggles the display of the actionbars backdrop."] = "切换动作条背景的显示。" -L["The frame won't show unless you mouse over it."] = "除非鼠标悬停,否则框架不会显示。" -L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "继承全局淡出效果,鼠标悬停、选择目标、设置焦点、失去生命值、进入战斗将移除透明度。否则,它将使用一般动作条设置中的透明度级别作为全局淡出的透明度。" +L["Toggles the display of the actionbar's backdrop."] = "切换动作条背景的显示。" +L["The frame will not be displayed unless hovered over."] = "除非鼠标悬停,否则框架不会显示。" +L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "继承全局淡出效果,鼠标悬停、选择目标、设置焦点、失去生命值、进入战斗将移除透明度。否则,它将使用一般动作条设置中的透明度级别作为全局淡出的透明度。" L["The first button anchors itself to this point on the bar."] = "第一个按钮固定在动作条上的这个点。" L["Right-click the item while holding the modifier to blacklist it. Blacklisted items will not show up on the bar.\nUse /questbarRestore to purge the blacklist."] = "按住修饰键的同时右键点击物品将其加入黑名单。黑名单中的物品不会在动作条上显示。\n使用 /questbarRestore 清除黑名单。" -L["The amount of buttons to display."] = "要显示的按钮数量。" -L["The amount of buttons to display per row."] = "每行显示的按钮数量。" +L["The number of buttons to display."] = "要显示的按钮数量。" +L["The number of buttons to display per row."] = "每行显示的按钮数量。" L["The size of the action buttons."] = "动作按钮的大小。" -L["The spacing between buttons."] = "按钮之间的间距。" -L["The spacing between the backdrop and the buttons."] = "背景和按钮之间的间距。" -L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."] = "将背景的高度或宽度乘以此值。如果你希望在一个背景后面有多个动作条,这很有用。" -L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"] = "这就像一个宏,你可以运行不同的情况来让动作条以不同方式显示/隐藏。\n 例如:'[combat] showhide'" -L["Adds anchoring options to movers' nudges."] = "为移动器的微调添加锚点选项。" -L["Mod-clicking an item suggest a skill/item to process it."] = "按住修饰键点击物品会建议处理它的技能/物品。" -L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = +L["Spacing between the buttons."] = "按钮之间的间距。" +L["Spacing between the backdrop and the buttons."] = "背景和按钮之间的间距。" +L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."] = "将背景的高度或宽度乘以此值。如果你希望在一个背景后面有多个动作条,这很有用。" +L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"] = "这就像一个宏,你可以运行不同的情况来让动作条以不同方式显示/隐藏。\n 例如:'[combat] showhide'" +L["Adds anchoring options to the movers' nudges."] = "为移动器的微调添加锚点选项。" +L["Mod-clicking an item suggests a skill/item to process it."] = "按住修饰键点击物品会建议处理它的技能/物品。" +L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = "按住%s的同时左键点击堆叠可将其分为两半;要合并可用副本,请右键点击。\n\n还修改了SplitStackFrame,使用编辑框而不是箭头。" L["Extends the bags functionality."] = "扩展背包功能。" -L["Handles automated repositioning of the newly received items."] = "处理新收到物品的自动重新定位。" -L["Default method: type > inventoryslotid > ilvl > name."] = "默认方法:类型 > 物品栏位ID > 物品等级 > 名称。" +L["Default method: type > inventory slot ID > item level > name."] = "默认方法:类型 > 物品栏位ID > 物品等级 > 名称。" L["Listed ItemIDs will not get sorted."] = "列出的物品ID不会被排序。" -L["Double-click the title text to minimize the section."] = "双击标题文本以最小化该部分。" -L["Minimized section's line color."] = "最小化部分的线条颜色。" L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"] = "例如:Interface\\Icons\\INV_Misc_QuestionMark" L["Invalid condition format: "] = "无效的条件格式:" L["The generated custom sorting method did not return a function."] = "生成的自定义排序方法没有返回函数。" @@ -98,26 +95,26 @@ L["The loaded custom sorting method did not return a function."] = "加载的自 L["Item received: "] = "收到物品:" L[" added."] = " 已添加。" L[" removed."] = " 已移除。" -L["Handles automated repositioning of the newly received items.".. +L["Handles the automated repositioning of the newly received items.".. "\nSyntax: filter@value\n\n".. "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. "Look up GetItemInfo API for more info on filters. ".. "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. "Example usage (priest t8 or Shadowmourne):\n".. "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. + "The below one notifies of the newly acquired items.\n\n".. "local icon = GetContainerItemInfo(bagID, slotID)\n".. "local _, link = GetItemInfo(itemID)\n".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. @@ -126,16 +123,16 @@ L["Handles automated repositioning of the newly received items.".. "处理新获得物品的自动重新定位。".. "\n语法: 过滤器@值\n\n".. "可用过滤器:\n".. - "id@数字 - 匹配物品ID,\n".. - "name@字符串 - 匹配名称,\n".. - "subtype@字符串 - 匹配子类型,\n".. - "ilvl@数字 - 匹配物品等级,\n".. - "uselevel@数字 - 匹配装备等级,\n".. - "quality@数字 - 匹配品质,\n".. - "equipslot@数字 - 匹配库存栏位ID,\n".. - "maxstack@数字 - 匹配堆叠上限,\n".. - "price@数字 - 匹配售价,\n\n".. - "tooltip@字符串 - 匹配提示文本,\n\n".. + " id@数字 - 匹配物品ID,\n".. + " name@字符串 - 匹配名称,\n".. + " subtype@字符串 - 匹配子类型,\n".. + " ilvl@数字 - 匹配物品等级,\n".. + " uselevel@数字 - 匹配装备等级,\n".. + " quality@数字 - 匹配品质,\n".. + " equipslot@数字 - 匹配库存栏位ID,\n".. + " maxstack@数字 - 匹配堆叠上限,\n".. + " price@数字 - 匹配售价,\n\n".. + " tooltip@字符串 - 匹配提示文本,\n\n".. "所有字符串匹配不区分大小写,仅匹配字母数字符号。适用标准lua逻辑。".. "查看GetItemInfo API以获取更多关于过滤器的信息。".. "使用GetAuctionItemClasses和GetAuctionItemSubClasses(与拍卖行相同)获取本地化的类型和子类型值。\n\n".. @@ -148,6 +145,47 @@ L["Handles automated repositioning of the newly received items.".. "icon = gsub(icon, '\124', '\124\124')\n".. "local string = '\124T' .. icon .. ':16:16\124t' .. link\n".. "print('获得物品: ' .. string)" +L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "语法:过滤器@值\n\n".. + "可用过滤器:\n".. + " id@数字 - 匹配物品ID,\n".. + " name@字符串 - 匹配名称,\n".. + " type@字符串 - 匹配类型,\n".. + " subtype@字符串 - 匹配子类型,\n".. + " ilvl@数字 - 匹配物品等级,\n".. + " uselevel@数字 - 匹配装备等级,\n".. + " quality@数字 - 匹配品质,\n".. + " equipslot@数字 - 匹配背包栏位ID,\n".. + " maxstack@数字 - 匹配堆叠上限,\n".. + " price@数字 - 匹配售价,\n".. + " tooltip@字符串 - 匹配提示文本。\n\n".. + "所有字符串匹配不区分大小写,且仅匹配字母数字符号。\n".. + "适用标准lua分支逻辑(与/或/括号等)。\n\n".. + "使用示例(牧师t8或暗影之哀伤):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["Available Item Types"] = "可用物品类型" +L["Lists all available item subtypes for each available item type."] = + "列出每个可用物品类型的所有可用物品子类型。" +L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."] = + "与商人互动时按住此键会购买所有符合自动购买设置的物品。\n".. + "在购买列表条目上进行模组点击,无视'@数量'规则,只购买一个符合条件的物品。" L["Default method: type > inventoryslotid > ilvl > name.\n\n".. "Accepts custom functions (bagID and slotID are available at the a/b.bagID/slotID).\n\n".. "function(a,b)\n".. @@ -171,7 +209,7 @@ L["Syntax:".. "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -181,13 +219,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. @@ -210,13 +248,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(玩家获得/失去了一个光环)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, '不良法术')".. "\nthen print(UnitName('party'..i)..'受到了影响!')".. @@ -224,7 +262,7 @@ L["Syntax:".. "\n\n此模块解析字符串,所以尽量严格遵循语法,否则可能无法正常工作。" L["Highlights auras."] = "高亮光环。" L["E.g. 42292"] = "例如 42292" -L["Aplies highlights to all auras passing the selected filter."] = "高亮所有通过选定过滤器的光环。" +L["Applies highlights to all auras passing the selected filter."] = "高亮所有通过选定过滤器的光环。" L["Priority: spell, filter, curable/stealable."] = "优先级:法术、过滤器、可治疗/可偷取。" L["If toggled, the GLOBAL Spell or Filter entry values would be used."] = "如果切换,将使用全局法术或过滤器条目值。" L["Makes auras grow sideswise."] = "使光环向两侧扩展。" @@ -236,7 +274,15 @@ L["Right-click a player buff to cancel it."] = "右键点击玩家增益效果 L["Disables debuffs desaturation."] = "禁用 debuff 去饱和度。" L["Saturated Debuffs"] = "饱和 debuffs" L["Confirm Rolls"] = "确认掷骰" -L["Quest Items and Money"] = "任务物品和金钱" +L["Auto Pickup"] = "自動拾取" +L["Swift Buy"] = "快速购买" +L["Buys out items automatically."] = "自动购买物品。" +L["Failsafe"] = "故障保护" +L["Enables popup confirmation dialog."] = "启用弹出确认对话框。" +L["Add Set"] = "添加套装" +L["Delete Set"] = "删除套装" +L["Select Set"] = "选择套装" +L["Auto Buy"] = "自动购买" L["Fill Delete"] = "填写删除" L["Gossip"] = "对话" L["Accept Quest"] = "接受任务" @@ -272,7 +318,6 @@ L["Select Container Type"] = "选择容器类型" L["Settings"] = "设置" L["Add Section"] = "添加部分" L["Delete Section"] = "删除部分" -L["Section Length"] = "部分长度" L["Select Section"] = "选择部分" L["Section Priority"] = "部分优先级" L["Section Spacing"] = "部分间距" @@ -280,8 +325,6 @@ L["Collection Method"] = "收集方法" L["Sorting Method"] = "排序方法" L["Ignore Item (by ID)"] = "忽略物品(按ID)" L["Remove Ignored"] = "移除已忽略" -L["Minimize"] = "最小化" -L["Line Color"] = "线条颜色" L["Title"] = "标题" L["Color"] = "颜色" L["Attach to Icon"] = "附加到图标" @@ -447,12 +490,10 @@ L["Add Texture Path"] = "添加材质路径" L["Remove Selected Texture"] = "移除所选材质" L["Titles"] = "头衔" L["Reaction Color"] = "反应颜色" -L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"] = "使用 /addOccupation 命令时按住此键以清除当前目标/鼠标悬停对象的职业列表。\n别忘了解除修饰键+按键绑定!" L["Color based on reaction type."] = "根据反应类型着色。" L["Nameplates"] = "姓名板" L["Unitframes"] = "单位框架" -L["An icon similar to the minimap search.\n\nTooltip scanning, might not be precise.\n\nFor consistency reasons, no keywards are added by defult, use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."] = - "类似于小地图搜索的图标。\n\n工具提示扫描,可能不准确。\n\n为了保持一致性,默认情况下不添加任何关键词,请使用 /addOccupation 命令自行标记适当的关键词(每个独特的职业文本只需做一次)。" +L["An icon similar to the minimap search."] = "类似于小地图搜索的图标。" L["Displays player guild text."] = "显示玩家的公会文本。" L["Displays NPC occupation text."] = "显示NPC的职业文本。" L["Strata"] = "层级" @@ -475,40 +516,6 @@ L["Unmark all plates."] = "取消所有姓名板的标记。" L["Usage: '/qmark' macro bound to a key of your choice.\n\nDon't forget to also unbind your modifier keybinds!"] = "用法:将 '/qmark' 宏绑定到您选择的按键。\n\n不要忘记解除您的修饰键绑定!" L["Use Backdrop"] = "使用背景" -L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."] = - "使用方法:\n%%d=%%s\n\n%%d - 下列表中的索引\n%%s - 要查找的关键词\n\n图标索引:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\n也可以使用'/addOccupation %%d'斜杠命令,其中%%d是可选的图标索引。".. - "如果未提供索引,此命令将循环所有可用图标。适用于目标或鼠标悬停,以鼠标悬停为优先。" L["Linked Style Filter Triggers"] = "链接的样式过滤器触发器" L["Select Link"] = "选择链接" L["New Link"] = "新链接" @@ -613,7 +620,7 @@ L["Disable Event"] = "禁用事件" L["School"] = "学派" L["Use School Colors"] = "使用学派颜色" L["Colors"] = "颜色" -L["Colors (School)"] = "颜色(学派)" +L["Color (School)"] = "颜色(系别)" L["Animation Type"] = "动画类型" L["Custom Animation"] = "自定义动画" L["Flag Settings"] = "标志设置" @@ -699,7 +706,7 @@ L["Rare Elite"] = "稀有精英" L["Class Spec Icons"] = "职业专精图标" L["Classification Textures"] = "分类材质" L["Use Nameplates' Icons"] = "使用姓名板图标" -L["Color enemy npc icon based on the unit type."] = "根据单位类型为敌对NPC图标着色。" +L["Color enemy NPC icon based on the unit type."] = "根据单位类型为敌对NPC图标着色。" L["Strata and Level"] = "层级和等级" L["Warrior"] = "战士" L["Warlock"] = "术士" @@ -771,7 +778,6 @@ L["On meeting multiple conditions, colors from the tab with the highest priority L["Copy Tab"] = "复制标签" L["Select a tab to copy its settings onto the current tab."] = "选择一个标签将其设置复制到当前标签。" L["Flash"] = "闪烁" -L["Toggle color flash for the current tab."] = "切换当前标签的颜色闪烁。" L["Speed"] = "速度" L["Glow"] = "发光" L["Determines which glow to apply when statusbars are not detached from frame."] = "决定当状态条未从框架分离时应用哪种发光效果。" @@ -788,7 +794,7 @@ L["Disabled unless classbar is enabled."] = "除非启用职业条,否则禁 L["InfoPanel Color"] = "信息面板颜色" L["Disabled unless infopanel is enabled."] = "除非启用信息面板,否则禁用。" L["ClassBar Adapt To"] = "职业条适应于" -L["Copies color of the selected bar."] = "复制所选条的颜色。" +L["Copies the color of the selected bar."] = "复制所选条的颜色。" L["InfoPanel Adapt To"] = "信息面板适应于" L["Override Mode"] = "覆盖模式" L["'None' - threat borders highlight will be prioritized over this one".. "\n'Threat' - this highlight will be prioritized."] = "'无' - 威胁边框高亮将优先于此高亮".. "\n'威胁' - 此高亮将优先。" @@ -803,33 +809,41 @@ L["Handle only player combat log events."] = "仅处理玩家战斗日志事件 L["Rotate Icon"] = "旋转图标" L["Usage example:".. "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/5]@@ - 根据相关标签(在上面的例子中:'player' - 目标单位;'Power' - 目标状态条;'3' - 目标标签)是否处于活动状态来返回 true/false(提及相同单位/群组的功能已禁用;不是递归的)".. + "\n local r, g, b = ElvUF_Target.Health:GetStatusBarColor()".. + "\n return true, {mR = r, mG = g, mB = b}".. + "\nelseif UnitIsUnit(unit, 'target') then".. + "\n return true".. + "\nend".. + "\n\n@@[raid, Health, 2, >5]@@ - 根据相关标签(在上面的例子中:'player' - 目标单位;'Power' - 目标状态条;'3' - 目标标签)是否处于活动状态来返回 true/false".. "\n(>/>=/<=/=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = + "处理自动物品定位。\n".. + "语法:filter@value\n\n".. + "可用过滤器:\n".. + " id@number - 匹配 itemID,\n".. + " name@string - 匹配名称,\n".. + " type@string - 匹配类型,\n".. + " subtype@string - 匹配子类型,\n".. + " ilvl@number - 匹配物品等级,\n".. + " uselevel@number - 匹配装备等级,\n".. + " quality@number - 匹配品质,\n".. + " equipslot@number - 匹配 InventorySlotID,\n".. + " maxstack@number - 匹配堆叠上限,\n".. + " price@number - 匹配售价,\n".. + " tooltip@string - 匹配提示文字,\n".. + " set@setName - 匹配装备套装物品。\n\n".. + "所有字符串匹配不区分大小写,仅匹配字母数字符号。\n".. + "标准 Lua 逻辑(and/or/括号等)适用。\n\n".. + "使用示例(牧师 t8 或 Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne。\n\n".. + "支持自定义函数(bagID、slotID、itemID 可用)。\n".. + "以下示例通知新获取的物品。\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('获得物品:' .. string)" +L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "语法:filter@value@amount\n\n".. + "可用过滤器:\n".. + " id@number@amount(+)/+ - 匹配 itemID,\n".. + " name@string@amount(+)/+ - 匹配名称,\n".. + " type@string@amount(+)/+ - 匹配类型,\n".. + " subtype@string@amount(+)/+ - 匹配子类型,\n".. + " ilvl@number@amount(+)/+ - 匹配物品等级,\n".. + " uselevel@number@amount(+)/+ - 匹配装备等级,\n".. + " quality@number@amount(+)/+ - 匹配品质,\n".. + " equipslot@number@amount(+)/+ - 匹配 InventorySlotID,\n".. + " maxstack@number@amount(+)/+ - 匹配堆叠上限,\n".. + " price@number@amount(+)/+ - 匹配售价,\n".. + " tooltip@string@amount(+)/+ - 匹配提示文字。\n\n".. + "可选的 'amount' 部分可以是:\n".. + " 一个数字 - 购买固定数量,\n".. + " + 符号 - 补充现有部分堆叠或购买新的,\n".. + " 两者(例如 5+) - 购买足够的物品以达到指定总数(此例中为 5),\n".. + " 省略 - 默认值为 1。\n\n".. + "所有字符串匹配不区分大小写,仅匹配字母数字符号。\n".. + "标准 Lua 逻辑(and/or/括号等)适用。\n\n".. + "使用示例(牧师 t8 或 Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne。" +L["PERIODIC"] = "周期性" +L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."] = "在使用 /addOccupation 命令时按住此键以清除当前目标/鼠标悬停 NPC 的列表." +L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."] = "在目标/鼠标悬停在 NPC 上时使用 /addOccupation 斜杠命令将其添加到列表中。再次使用以循环." +L["Style Filter Icons"] = "样式过滤器图标" +L["Custom icons for the style filter."] = "样式过滤器的自定义图标." +L["Whitelist"] = "白名单" +L["X Direction"] = "X方向" +L["Y Direction"] = "Y方向" +L["Create Icon"] = "创建图标" +L["Delete Icon"] = "删除图标" +L["0 to match frame width."] = "0 以匹配框架宽度。" +L["Remove a NPC"] = "移除 NPC" +L["Change a NPC's Occupation"] = "更改 NPC 的职业" +L["...to the currently selected one."] = "...为当前选择的职业。" +L["Select Occupation"] = "选择职业" \ No newline at end of file diff --git a/Locales/zhTW.lua b/Locales/zhTW.lua index ca233d1..4659f29 100644 --- a/Locales/zhTW.lua +++ b/Locales/zhTW.lua @@ -2,16 +2,16 @@ local E = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, Global local L = E.Libs.ACL:NewLocale("ElvUI", "zhTW") L["Hits the 'Confirm' button automatically."] = "自動點擊'確認'按鈕。" -L["Picks up quest items and money automatically."] = "自動拾取任務物品和金錢。" -L["Fills 'DELETE' field automatically."] = "自動填寫'刪除'欄位。" -L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."] = "如果只有一個對話選項可用,則自動選擇第一個選項,除非按住修飾鍵。\n對於重要的事件觸發要小心,沒有故障保護機制。" +L["Picks up items and money automatically."] = "自動拾取物品和金錢。" +L["Automatically fills the 'DELETE' field."] = "自動填寫'刪除'欄位。" +L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."] = "如果只有一個對話選項可用,則自動選擇第一個選項,除非按住修飾鍵。\n對於重要的事件觸發要小心,沒有故障保護機制。" L["Accepts and turns in quests automatically while holding a modifier."] = "按住修飾鍵時自動接受和提交任務。" L["Loot info wiped."] = "拾取資訊已清除。" L["/lootinfo slash command to get a quick rundown of the recent lootings.\n\nUsage: /lootinfo Apple 60\n'Apple' - item/player name \n(search @self to get player loot)\n'60' - \ntime limit (<60 seconds ago), optional,\n/lootinfo !wipe - purge loot cache."] = "/lootinfo 命令以快速查看最近的戰利品。\n\n用法: /lootinfo 蘋果 60\n'蘋果' - 物品/玩家名稱 \n(搜尋 @self 以獲取玩家的戰利品)\n'60' - \n時間限制(<60秒前),可選,\n/lootinfo !wipe - 清除戰利品快取。" -L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "在某些訊息中為線上好友和公會成員的名字著色,並為擲骰添加樣式。\n已處理的聊天氣泡在你使用 /reload 之前不會被重新設置樣式。" +L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."] = "在某些訊息中為線上好友和公會成員的名字著色,並為擲骰添加樣式。\n已處理的聊天氣泡在你使用 /reload 之前不會被重新設置樣式。" L["Colors loot roll messages for you and other players."] = "為你和其他玩家的拾取擲骰訊息著色。" L["Loot rolls icon size."] = "拾取擲骰圖示大小。" -L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "重新設置拾取條樣式。\n需要啟用'拾取擲骰'(一般 -> BlizzUI改進 -> 拾取擲骰)(切換此模組會自動啟用它)。" +L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."] = "重新設置拾取條樣式。\n需要啟用'拾取擲骰'(一般 -> BlizzUI改進 -> 拾取擲骰)(切換此模組會自動啟用它)。" L["Displays the name of the player pinging the minimap."] = "顯示在小地圖上發出標記的玩家名稱。" L["Displays the currently held currency amount next to the item prices."] = "在物品價格旁顯示當前持有的貨幣數量。" L["Narrows down the World(..Frame)."] = "縮小World(..Frame)。" @@ -28,7 +28,7 @@ L["Adds shadows to all of the frames.\nDoes nothing unless you replace your ElvU L["Combat state notification alerts."] = "戰鬥狀態通知警報。" L["Custom editbox position and size."] = "自訂編輯框位置和大小。" L["Usage:".. - "\n/tnote list - returns all eixting notes".. + "\n/tnote list - returns all existing notes".. "\n/tnote wipe - clears all existing notes".. "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. "\n/tnote 1 get - same as set, returns existing notes".. @@ -69,28 +69,25 @@ L["Usage:".. "\n (1-percentage)*255, percentage*255)" L["Adds an icon next to chat hyperlinks."] = "在聊天超連結旁添加一個圖標。" L["A new action bar that collects usable quest items from your bag.\n\nDue to state actions limit, this module overrides bar10 created by ElvUI Extra Action Bars."] = "一個新的動作條,用於收集背包中可用的任務物品。\n\n由於狀態動作限制,該模組會覆蓋ElvUI額外動作條創建的bar10。" -L["Toggles the display of the actionbars backdrop."] = "切換動作條背景的顯示。" -L["The frame won't show unless you mouse over it."] = "除非滑鼠懸停,否則框架不會顯示。" -L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "繼承全局淡出效果,滑鼠懸停、選擇目標、設置焦點、失去生命值、進入戰鬥將移除透明度。否則,它將使用一般動作條設置中的透明度級別作為全局淡出的透明度。" +L["Toggles the display of the actionbar's backdrop."] = "切換動作條背景的顯示。" +L["The frame will not be displayed unless hovered over."] = "除非滑鼠懸停,否則框架不會顯示。" +L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."] = "繼承全局淡出效果,滑鼠懸停、選擇目標、設置焦點、失去生命值、進入戰鬥將移除透明度。否則,它將使用一般動作條設置中的透明度級別作為全局淡出的透明度。" L["The first button anchors itself to this point on the bar."] = "第一個按鈕固定在動作條上的這個點。" L["Right-click the item while holding the modifier to blacklist it. Blacklisted items will not show up on the bar.\nUse /questbarRestore to purge the blacklist."] = "按住修飾鍵的同時右鍵點擊物品將其加入黑名單。黑名單中的物品不會在動作條上顯示。\n使用 /questbarRestore 清除黑名單。" -L["The amount of buttons to display."] = "要顯示的按鈕數量。" -L["The amount of buttons to display per row."] = "每行顯示的按鈕數量。" +L["The number of buttons to display."] = "要顯示的按鈕數量。" +L["The number of buttons to display per row."] = "每行顯示的按鈕數量。" L["The size of the action buttons."] = "動作按鈕的大小。" -L["The spacing between buttons."] = "按鈕之間的間距。" -L["The spacing between the backdrop and the buttons."] = "背景和按鈕之間的間距。" -L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."] = "將背景的高度或寬度乘以此值。如果你希望在一個背景後面有多個動作條,這很有用。" -L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"] = "這就像一個巨集,你可以運行不同的情況來讓動作條以不同方式顯示/隱藏。\n 例如:'[combat] showhide'" -L["Adds anchoring options to movers' nudges."] = "為移動器的微調添加錨點選項。" -L["Mod-clicking an item suggest a skill/item to process it."] = "按住 Mod 鍵點擊物品會建議處理該物品的技能/物品。" -L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = +L["Spacing between the buttons."] = "按鈕之間的間距。" +L["Spacing between the backdrop and the buttons."] = "背景和按鈕之間的間距。" +L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."] = "將背景的高度或寬度乘以此值。如果你希望在一個背景後面有多個動作條,這很有用。" +L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"] = "這就像一個巨集,你可以運行不同的情況來讓動作條以不同方式顯示/隱藏。\n 例如:'[combat] showhide'" +L["Adds anchoring options to the movers' nudges."] = "為移動器的微調添加錨點選項。" +L["Mod-clicking an item suggests a skill/item to process it."] = "按住 Mod 鍵點擊物品會建議處理該物品的技能/物品。" +L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."] = "按住%s的同時左鍵點擊堆疊可將其分為兩半;要合併可用副本,請右鍵點擊。\n\n還修改了SplitStackFrame,使用編輯框而不是箭頭。" L["Extends the bags functionality."] = "擴展背包功能。" -L["Handles automated repositioning of the newly received items."] = "處理新獲得物品的自動重新定位。" -L["Default method: type > inventoryslotid > ilvl > name."] = "預設方法:類型 > 背包欄位ID > 物品等級 > 名稱。" +L["Default method: type > inventory slot ID > item level > name."] = "預設方法:類型 > 背包欄位ID > 物品等級 > 名稱。" L["Listed ItemIDs will not get sorted."] = "列出的物品ID不會被排序。" -L["Double-click the title text to minimize the section."] = "雙擊標題文字以最小化該部分。" -L["Minimized section's line color."] = "最小化部分的線條顏色。" L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"] = "例如:Interface\\Icons\\INV_Misc_QuestionMark" L["Invalid condition format: "] = "無效的條件格式:" L["The generated custom sorting method did not return a function."] = "生成的自定義排序方法未返回函數。" @@ -98,26 +95,26 @@ L["The loaded custom sorting method did not return a function."] = "載入的自 L["Item received: "] = "收到物品:" L[" added."] = " 已添加。" L[" removed."] = " 已移除。" -L["Handles automated repositioning of the newly received items.".. +L["Handles the automated repositioning of the newly received items.".. "\nSyntax: filter@value\n\n".. "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. "Look up GetItemInfo API for more info on filters. ".. "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. "Example usage (priest t8 or Shadowmourne):\n".. "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. + "The below one notifies of the newly acquired items.\n\n".. "local icon = GetContainerItemInfo(bagID, slotID)\n".. "local _, link = GetItemInfo(itemID)\n".. "icon = gsub(icon, '\\124', '\\124\\124')\n".. @@ -126,16 +123,16 @@ L["Handles automated repositioning of the newly received items.".. "處理新獲得物品的自動重新定位。".. "\n語法: 過濾器@值\n\n".. "可用過濾器:\n".. - "id@數字 - 匹配物品ID,\n".. - "name@字串 - 匹配名稱,\n".. - "subtype@字串 - 匹配子類型,\n".. - "ilvl@數字 - 匹配物品等級,\n".. - "uselevel@數字 - 匹配裝備等級,\n".. - "quality@數字 - 匹配品質,\n".. - "equipslot@數字 - 匹配庫存欄位ID,\n".. - "maxstack@數字 - 匹配堆疊上限,\n".. - "price@數字 - 匹配售價,\n\n".. - "tooltip@字串 - 匹配提示文字,\n\n".. + " id@數字 - 匹配物品ID,\n".. + " name@字串 - 匹配名稱,\n".. + " subtype@字串 - 匹配子類型,\n".. + " ilvl@數字 - 匹配物品等級,\n".. + " uselevel@數字 - 匹配裝備等級,\n".. + " quality@數字 - 匹配品質,\n".. + " equipslot@數字 - 匹配庫存欄位ID,\n".. + " maxstack@數字 - 匹配堆疊上限,\n".. + " price@數字 - 匹配售價,\n\n".. + " tooltip@字串 - 匹配提示文字,\n\n".. "所有字串匹配不區分大小寫,僅匹配字母數字符號。適用標準lua邏輯。".. "查看GetItemInfo API以獲取更多關於過濾器的資訊。".. "使用GetAuctionItemClasses和GetAuctionItemSubClasses(與拍賣行相同)獲取本地化的類型和子類型值。\n\n".. @@ -148,6 +145,47 @@ L["Handles automated repositioning of the newly received items.".. "icon = gsub(icon, '\124', '\124\124')\n".. "local string = '\124T' .. icon .. ':16:16\124t' .. link\n".. "print('獲得物品: ' .. string)" +L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "語法:過濾器@值\n\n".. + "可用過濾器:\n".. + " id@數字 - 匹配物品ID,\n".. + " name@字串 - 匹配名稱,\n".. + " type@字串 - 匹配類型,\n".. + " subtype@字串 - 匹配子類型,\n".. + " ilvl@數字 - 匹配物品等級,\n".. + " uselevel@數字 - 匹配裝備等級,\n".. + " quality@數字 - 匹配品質,\n".. + " equipslot@數字 - 匹配背包欄位ID,\n".. + " maxstack@數字 - 匹配堆疊上限,\n".. + " price@數字 - 匹配售價,\n".. + " tooltip@字串 - 匹配提示文字。\n\n".. + "所有字串匹配不區分大小寫,且僅匹配字母數字符號。\n".. + "適用標準lua分支邏輯(和/或/括號等)。\n\n".. + "使用範例(牧師t8或暗影之悲):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne." +L["Available Item Types"] = "可用物品類型" +L["Lists all available item subtypes for each available item type."] = + "列出每個可用物品類型的所有可用物品子類型。" +L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."] = + "與商人互動時按住此鍵會購買所有符合自動購買設定的物品。\n".. + "在購買清單條目上進行模組點擊,即可無視'@數量'規則,只購買一件符合條件的物品。" L["Default method: type > inventoryslotid > ilvl > name.\n\n".. "Accepts custom functions (bagID and slotID are available at the a/b.bagID/slotID).\n\n".. "function(a,b)\n".. @@ -171,7 +209,7 @@ L["Syntax:".. "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -181,13 +219,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. @@ -210,13 +248,13 @@ L["Syntax:".. "\n\nUNIT_AURA[1=player]@@@".. "\nprint(玩家獲得/失去了一個光環)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, '不良法術')".. "\nthen print(UnitName('party'..i)..'受到了影響!')".. @@ -224,7 +262,7 @@ L["Syntax:".. "\n\n此模組解析字符串,所以盡量嚴格遵循語法,否則可能無法正常工作。" L["Highlights auras."] = "突出顯示光環。" L["E.g. 42292"] = "例如 42292" -L["Aplies highlights to all auras passing the selected filter."] = "突出顯示所有通過選擇過濾器的光環。" +L["Applies highlights to all auras passing the selected filter."] = "突出顯示所有通過選擇過濾器的光環。" L["Priority: spell, filter, curable/stealable."] = "優先級:法術、過濾器、可治療/可偷竊。" L["If toggled, the GLOBAL Spell or Filter entry values would be used."] = "如果切換,將使用全局法術或過濾器條目值。" L["Makes auras grow sideswise."] = "使光環向兩側擴展。" @@ -236,7 +274,15 @@ L["Right-click a player buff to cancel it."] = "右鍵點擊玩家的增益效 L["Disables debuffs desaturation."] = "禁用減少 debuff 飽和度。" L["Saturated Debuffs"] = "飽和 debuffs" L["Confirm Rolls"] = "確認擲骰" -L["Quest Items and Money"] = "任務物品和金錢" +L["Auto Pickup"] = "自動拾取" +L["Swift Buy"] = "快速購買" +L["Buys out items automatically."] = "自動購買物品。" +L["Failsafe"] = "故障保護" +L["Enables popup confirmation dialog."] = "啟用彈出確認對話框。" +L["Add Set"] = "新增套裝" +L["Delete Set"] = "刪除套裝" +L["Select Set"] = "選擇套裝" +L["Auto Buy"] = "自動購買" L["Fill Delete"] = "填寫刪除" L["Gossip"] = "對話" L["Accept Quest"] = "接受任務" @@ -272,7 +318,6 @@ L["Select Container Type"] = "選擇容器類型" L["Settings"] = "設置" L["Add Section"] = "添加部分" L["Delete Section"] = "刪除部分" -L["Section Length"] = "部分長度" L["Select Section"] = "選擇部分" L["Section Priority"] = "部分優先級" L["Section Spacing"] = "部分間距" @@ -280,8 +325,6 @@ L["Collection Method"] = "收集方法" L["Sorting Method"] = "排序方法" L["Ignore Item (by ID)"] = "忽略物品(按ID)" L["Remove Ignored"] = "移除已忽略" -L["Minimize"] = "最小化" -L["Line Color"] = "線條顏色" L["Title"] = "標題" L["Color"] = "顏色" L["Attach to Icon"] = "附加到圖示" @@ -447,13 +490,10 @@ L["Add Texture Path"] = "添加材質路徑" L["Remove Selected Texture"] = "移除所選材質" L["Titles"] = "頭銜" L["Reaction Color"] = "反應顏色" -L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"] = - "使用 /addOccupation 命令時按住此鍵以清除當前目標/滑鼠懸停對象的職業列表。\n別忘了解除修飾鍵+按鍵綁定!" L["Color based on reaction type."] = "根據反應類型著色。" L["Nameplates"] = "名條" L["Unitframes"] = "單位框架" -L["An icon similar to the minimap search.\n\nTooltip scanning, might not be precise.\n\nFor consistency reasons, no keywards are added by defult, use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."] = - "類似於小地圖搜索的圖標。\n\n工具提示掃描,可能不準確。\n\n為了一致性,默認情況下不添加任何關鍵詞,請使用 /addOccupation 命令自行標記適當的關鍵詞(每個獨特的職業文本只需做一次)。" +L["An icon similar to the minimap search."] = "類似於小地圖搜索的圖標。" L["Displays player guild text."] = "顯示玩家的公會文本。" L["Displays NPC occupation text."] = "顯示NPC的職業文本。" L["Strata"] = "層級" @@ -476,40 +516,6 @@ L["Unmark all plates."] = "取消所有姓名板的標記。" L["Usage: '/qmark' macro bound to a key of your choice.\n\nDon't forget to also unbind your modifier keybinds!"] = "用法:將 '/qmark' 宏綁定到您選擇的按鍵。\n\n不要忘記解除您的修飾鍵綁定!" L["Use Backdrop"] = "使用背景" -L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."] = - "用法:\n%%d=%%s\n\n%%d - 下列表中的索引\n%%s - 要查找的關鍵詞\n\n圖標索引:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\n也可以使用'/addOccupation %%d'指令,其中%%d是可選的圖標索引。".. - "如果未提供索引,該命令將循環所有可用圖標。適用於目標或鼠標懸停,以鼠標懸停為優先。" L["Linked Style Filter Triggers"] = "連結的樣式過濾器觸發器" L["Select Link"] = "選擇連結" L["New Link"] = "新連結" @@ -614,7 +620,7 @@ L["Disable Event"] = "禁用事件" L["School"] = "學派" L["Use School Colors"] = "使用學派顏色" L["Colors"] = "顏色" -L["Colors (School)"] = "顏色(學派)" +L["Color (School)"] = "顏色(系別)" L["Animation Type"] = "動畫類型" L["Custom Animation"] = "自定義動畫" L["Flag Settings"] = "標誌設定" @@ -700,7 +706,7 @@ L["Rare Elite"] = "稀有精英" L["Class Spec Icons"] = "職業專精圖示" L["Classification Textures"] = "分類材質" L["Use Nameplates' Icons"] = "使用姓名板圖示" -L["Color enemy npc icon based on the unit type."] = "根據單位類型為敵對NPC圖示著色。" +L["Color enemy NPC icon based on the unit type."] = "根據單位類型為敵對NPC圖示著色。" L["Strata and Level"] = "層級和等級" L["Warrior"] = "戰士" L["Warlock"] = "術士" @@ -772,7 +778,6 @@ L["On meeting multiple conditions, colors from the tab with the highest priority L["Copy Tab"] = "複製標籤" L["Select a tab to copy its settings onto the current tab."] = "選擇一個標籤將其設置複製到當前標籤。" L["Flash"] = "閃爍" -L["Toggle color flash for the current tab."] = "切換當前標籤的顏色閃爍。" L["Speed"] = "速度" L["Glow"] = "發光" L["Determines which glow to apply when statusbars are not detached from frame."] = "決定當狀態條未從框架分離時應用哪種發光效果。" @@ -789,7 +794,7 @@ L["Disabled unless classbar is enabled."] = "除非啟用職業條,否則禁 L["InfoPanel Color"] = "信息面板顏色" L["Disabled unless infopanel is enabled."] = "除非啟用信息面板,否則禁用。" L["ClassBar Adapt To"] = "職業條適應於" -L["Copies color of the selected bar."] = "複製所選條的顏色。" +L["Copies the color of the selected bar."] = "複製所選條的顏色。" L["InfoPanel Adapt To"] = "信息面板適應於" L["Override Mode"] = "覆蓋模式" L["'None' - threat borders highlight will be prioritized over this one".. "\n'Threat' - this highlight will be prioritized."] = "'無' - 威脅邊框高亮將優先於此高亮".. "\n'威脅' - 此高亮將優先。" @@ -804,33 +809,41 @@ L["Handle only player combat log events."] = "僅處理玩家戰鬥日誌事件 L["Rotate Icon"] = "旋轉圖示" L["Usage example:".. "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/5]@@ - 根據相關標籤(在上面的例子中:'player' - 目標單位;'Power' - 目標狀態條;'3' - 目標標籤)是否處於活動狀態來返回 true/false(提及相同單位/群組的功能已禁用;不是遞歸的)".. + "\n local r, g, b = ElvUF_Target.Health:GetStatusBarColor()".. + "\n return true, {mR = r, mG = g, mB = b}".. + "\nelseif UnitIsUnit(unit, 'target') then".. + "\n return true".. + "\nend".. + "\n\n@@[raid, Health, 2, >5]@@ - 根據相關標籤(在上面的例子中:'player' - 目標單位;'Power' - 目標狀態條;'3' - 目標標籤)是否處於活動狀態來返回 true/false".. "\n(>/>=/<=/=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"] = + "處理自動物品定位。\n".. + "語法:filter@value\n\n".. + "可用過濾器:\n".. + " id@number - 匹配 itemID,\n".. + " name@string - 匹配名稱,\n".. + " type@string - 匹配類型,\n".. + " subtype@string - 匹配子類型,\n".. + " ilvl@number - 匹配物品等級,\n".. + " uselevel@number - 匹配裝備等級,\n".. + " quality@number - 匹配品質,\n".. + " equipslot@number - 匹配 InventorySlotID,\n".. + " maxstack@number - 匹配堆疊上限,\n".. + " price@number - 匹配售價,\n".. + " tooltip@string - 匹配提示文字,\n".. + " set@setName - 匹配裝備套裝物品。\n\n".. + "所有字串匹配不區分大小寫,僅匹配字母數字符號。\n".. + "標準 Lua 邏輯(and/or/括號等)適用。\n\n".. + "使用範例(牧師 t8 或 Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne。\n\n".. + "接受自定義函數(bagID、slotID、itemID 可用)。\n".. + "以下範例通知新獲得的物品。\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('獲得物品:' .. string)" +L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."] = + "語法:filter@value@amount\n\n".. + "可用過濾器:\n".. + " id@number@amount(+)/+ - 匹配 itemID,\n".. + " name@string@amount(+)/+ - 匹配名稱,\n".. + " type@string@amount(+)/+ - 匹配類型,\n".. + " subtype@string@amount(+)/+ - 匹配子類型,\n".. + " ilvl@number@amount(+)/+ - 匹配物品等級,\n".. + " uselevel@number@amount(+)/+ - 匹配裝備等級,\n".. + " quality@number@amount(+)/+ - 匹配品質,\n".. + " equipslot@number@amount(+)/+ - 匹配 InventorySlotID,\n".. + " maxstack@number@amount(+)/+ - 匹配堆疊上限,\n".. + " price@number@amount(+)/+ - 匹配售價,\n".. + " tooltip@string@amount(+)/+ - 匹配提示文字。\n\n".. + "可選的 'amount' 部分可以是:\n".. + " 一個數字 - 購買固定數量,\n".. + " + 符號 - 補充現有部分堆疊或購買新堆疊,\n".. + " 兩者(例如 5+) - 購買足夠的物品以達到指定總數(此例中為 5),\n".. + " 省略 - 默認為 1。\n\n".. + "所有字串匹配不區分大小寫,僅匹配字母數字符號。\n".. + "標準 Lua 邏輯(and/or/括號等)適用。\n\n".. + "使用範例(牧師 t8 或 Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne。" +L["PERIODIC"] = "週期性" +L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."] = "在使用 /addOccupation 命令時按住此鍵以清除當前目標/滑鼠懸停 NPC 的列表." +L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."] = "在目標/滑鼠懸停在 NPC 上時使用 /addOccupation 斜線命令將其添加到列表中。再次使用以循環." +L["Style Filter Icons"] = "樣式過濾器圖示" +L["Custom icons for the style filter."] = "樣式過濾器的自定義圖示." +L["Whitelist"] = "白名單" +L["X Direction"] = "X方向" +L["Y Direction"] = "Y方向" +L["Create Icon"] = "建立圖標" +L["Delete Icon"] = "刪除圖標" +L["0 to match frame width."] = "0 以匹配框架寬度。" +L["Remove a NPC"] = "移除 NPC" +L["Change a NPC's Occupation"] = "更改 NPC 的職業" +L["...to the currently selected one."] = "...為當前選擇的職業。" +L["Select Occupation"] = "選擇職業" \ No newline at end of file diff --git a/Modules/Blizzard/Automation.lua b/Modules/Blizzard/Automation.lua index 7e4d724..adf55bf 100644 --- a/Modules/Blizzard/Automation.lua +++ b/Modules/Blizzard/Automation.lua @@ -4,27 +4,294 @@ local mod = core:NewModule("Automation", "AceHook-3.0", "AceEvent-3.0") local modName = mod:GetName() -local pairs, select = pairs, select -local tinsert, tsort = table.insert, table.sort -local match, gsub, format = string.match, string.gsub, string.format +local _G, ipairs, select, type, unpack = _G, ipairs, select, type, unpack +local loadstring, pcall, tonumber, tostring = loadstring, pcall, tonumber, tostring +local tinsert, tremove, tconcat = table.insert, table.remove, table.concat +local gmatch, match, gsub, format, find, lower = string.gmatch, string.match, string.gsub, string.format, string.find, string.lower local ConfirmLootRoll, LootSlot, GetLootSlotInfo = ConfirmLootRoll, LootSlot, GetLootSlotInfo local GetNumLootItems, GetLootSlotLink = GetNumLootItems, GetLootSlotLink local QuestGetAutoAccept, AcceptQuest, CloseQuest, ConfirmAcceptQuest = QuestGetAutoAccept, AcceptQuest, CloseQuest, ConfirmAcceptQuest local GetNumQuestChoices, IsQuestCompletable, CompleteQuest, GetQuestReward = GetNumQuestChoices, IsQuestCompletable, CompleteQuest, GetQuestReward local GossipFrame, GetNumGossipOptions, GetGossipAvailableQuests = GossipFrame, GetNumGossipOptions, GetGossipAvailableQuests local GetGossipActiveQuests, SelectGossipOption = GetGossipActiveQuests, SelectGossipOption -local StaticPopupDialogs, StaticPopup_Hide = StaticPopupDialogs, StaticPopup_Hide -local IsModifierKeyDown, GetItemInfo = IsModifierKeyDown, GetItemInfo -local localizedQuestItemString = select(12,GetAuctionItemClasses()) -local DELETE_ITEM_CONFIRM_STRING = DELETE_ITEM_CONFIRM_STRING +local StaticPopupDialogs, StaticPopup_Hide, StaticPopup_Show = StaticPopupDialogs, StaticPopup_Hide, StaticPopup_Show +local IsModifierKeyDown, GetItemInfo, GetItemCount = IsModifierKeyDown, GetItemInfo, GetItemCount +local GetMerchantItemLink, BuyMerchantItem = GetMerchantItemLink, BuyMerchantItem +local GetAuctionItemClasses, GetAuctionItemSubClasses = GetAuctionItemClasses, GetAuctionItemSubClasses +local BROWSE_NO_RESULTS, BANKSLOTPURCHASE, DELETE_ITEM_CONFIRM_STRING = BROWSE_NO_RESULTS, BANKSLOTPURCHASE, DELETE_ITEM_CONFIRM_STRING +local YES, NO = YES, NO + +local methodFuncs, swiftBuyButton = {} +local scanner = CreateFrame("GameTooltip", "ExtrasAutomation_ScanningTooltip", nil, "GameTooltipTemplate") +scanner:SetOwner(WorldFrame, "ANCHOR_NONE") + +local inventorySlotIDs = { + ["INVTYPE_AMMO"] = 0, + ["INVTYPE_HEAD"] = 1, + ["INVTYPE_NECK"] = 2, + ["INVTYPE_SHOULDER"] = 3, + ["INVTYPE_BODY"] = 4, + ["INVTYPE_CHEST"] = 5, + ["INVTYPE_ROBE"] = 5, + ["INVTYPE_WAIST"] = 6, + ["INVTYPE_LEGS"] = 7, + ["INVTYPE_FEET"] = 8, + ["INVTYPE_WRIST"] = 9, + ["INVTYPE_HAND"] = 10, + ["INVTYPE_FINGER"] = 11, + ["INVTYPE_TRINKET"] = 13, + ["INVTYPE_CLOAK"] = 15, + ["INVTYPE_WEAPON"] = 16, + ["INVTYPE_SHIELD"] = 17, + ["INVTYPE_2HWEAPON"] = 16, + ["INVTYPE_WEAPONMAINHAND"] = 16, + ["INVTYPE_WEAPONOFFHAND"] = 17, + ["INVTYPE_HOLDABLE"] = 17, + ["INVTYPE_RANGED"] = 18, + ["INVTYPE_THROWN"] = 18, + ["INVTYPE_RELIC"] = 18, +} + +local filter = { + id = function(item) return item.id end, + type = function(item) return item.type and lower(gsub(item.type, '[%s%p]+', '')) end, + subtype = function(item) return item.subType and lower(gsub(item.subType, '[%s%p]+', '')) end, + ilvl = function(item) return item.ilvl end, + uselevel = function(item) return item.useLevel end, + quality = function(item) return item.quality end, + name = function(item) return item.name and lower(gsub(item.name, '[%s%p]+', '')) end, + equipslot = function(item) return inventorySlotIDs[item.equipSlot] end, + maxstack = function(item) return item.maxStack end, + price = function(item) return item.sellPrice end, + tooltip = function(item) + scanner:ClearLines() + scanner:SetHyperlink(item.link) + local tooltipText = '' + for i = 2, scanner:NumLines() do + local left = _G["ExtrasAutomation_ScanningTooltipTextLeft"..i]:GetText() + local right = _G["ExtrasAutomation_ScanningTooltipTextRight"..i]:GetText() + + tooltipText = tooltipText .. (left or '') + tooltipText = tooltipText .. (right or '') + end + return tooltipText + end, +} + +local function formatCondition(filterName, operator, value, amount) + if tonumber(value) then + return format('((filterFuncs.%s(item) and filterFuncs.%s(item) %s %s) and %s)', filterName, filterName, operator, value, amount) + elseif operator == '~=' then + return format('not find(filterFuncs.%s(item) or "", "%s", 1, true) and %s', filterName, lower(value), amount) + else + return format('find(filterFuncs.%s(item) or "", "%s", 1, true) and %s', filterName, lower(value), amount) + end +end + +local function parseCollectionString(conditions) + local formattedConditions = conditions + + for condition in gmatch(formattedConditions, '%S+@[<>=~!]*%S+') do + local pair, filterName, operator, value, amount = match(condition, '(([^%s%p]*)@(%p*)([^%s%p]*)@*([+%d]*))') + if filterName and filter[filterName] and value then + local formattedCondition = formatCondition(filterName, operator ~= '' and operator or '==', + value, amount ~= '' and (tonumber(amount) or format("'%s'", amount or 1)) or 1) + formattedConditions = gsub(formattedConditions, gsub(pair, "([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1"), formattedCondition) + else + core:print('FORMATTING', L["Automations"]) + return + end + end + + if formattedConditions ~= conditions then + return format([[ + return function(filterFuncs) + return function(item) + return %s + end + end + ]], formattedConditions) + end +end + +local function updateCollectionMethods(collectionMethod) + if not find(collectionMethod or "", '%S+') then + return + end + + local parsedString = parseCollectionString(collectionMethod) + if not parsedString then return end + + local luaFunction, errorMsg = loadstring(parsedString) + if luaFunction then + setfenv(luaFunction, {find = string.find}) + local success, customFuncGenerator = pcall(luaFunction) + if not success then + core:print('FAIL', L["Automations"], customFuncGenerator) + else + local customFunc = customFuncGenerator(filter) + + if type(customFunc) == "function" then + return function(itemInfo) + return itemInfo and customFunc(itemInfo) or false + end + else + core:print('LUA', L["Automations"], L["The generated custom looting method did not return a function."]) + end + end + else + core:print('LUA', L["Automations"], errorMsg) + end +end + +local function getItemDetails(itemID) + local itemName, itemLink, quality, itemLevel, useLevel, itemType, itemSubType, maxStack, equipSlot, _, sellPrice = GetItemInfo(itemID) + return { + id = tonumber(itemID), + name = itemName, + link = itemLink, + quality = quality, + ilvl = itemLevel, + useLevel = useLevel, + type = itemType, + subType = itemSubType, + equipSlot = equipSlot, + maxStack = maxStack, + sellPrice = sellPrice, + } +end + +local function createTex(button, texture, size) + local tex = button:CreateTexture(nil, "ARTWORK") + tex:SetTexture(texture) + tex:Point("CENTER") + tex:Size(size) + + return tex +end + + +local function updatePopupDialog(pending, popupsCount, index, itemLink, amount) + StaticPopupDialogs["CONFIRM_BUY_ITEM"..popupsCount] = { + text = format("%s %s x%s?", BANKSLOTPURCHASE, itemLink, amount), + button1 = YES, + button2 = NO, + OnAccept = function() + BuyMerchantItem(index, amount) + if #pending > 0 then + StaticPopup_Hide("CONFIRM_BUY_ITEM"..popupsCount) + updatePopupDialog(pending, popupsCount, unpack(tremove(pending))) + StaticPopup_Show("CONFIRM_BUY_ITEM"..popupsCount) + return true + end + end, + OnCancel = function() + if #pending > 0 then + StaticPopup_Hide("CONFIRM_BUY_ITEM"..popupsCount) + updatePopupDialog(pending, popupsCount, unpack(tremove(pending))) + StaticPopup_Show("CONFIRM_BUY_ITEM"..popupsCount) + return true + end + end, + timeout = 0, + whileDead = true, + hideOnEscape = true, + } +end + +local function buyMerchantStuff(collectionMethod, failsafe, buyOne) + local index = 1 + local staticOffset = 1 + local pending = {} + local itemLink = GetMerchantItemLink(index) + while itemLink do + local itemID = tonumber(match(itemLink, "item:(%d+)")) + local buyoutAmount = collectionMethod(getItemDetails(itemID)) + if buyoutAmount then + if buyOne then + buyoutAmount = 1 + end + if failsafe then + local popupsCount = staticOffset + local staticbuyoutAmount + if buyoutAmount == '+' then + local maxStack = select(8, GetItemInfo(itemID)) + local heldAmount = maxStack - GetItemCount(itemID) + staticbuyoutAmount = heldAmount > 0 and heldAmount or maxStack + else + local amount1, amount2 = match(buyoutAmount, '(%d*)+(%d*)') + local buyoutAmountVal = tonumber(amount1 or amount2) + if buyoutAmountVal then + local topAmount = buyoutAmountVal - GetItemCount(itemID) + if topAmount > 0 then + staticbuyoutAmount = topAmount + end + else + staticbuyoutAmount = tonumber(buyoutAmount) + end + end + if staticbuyoutAmount then + if popupsCount > 4 then + tinsert(pending, 1, {index, itemLink, staticbuyoutAmount}) + else + updatePopupDialog(pending, popupsCount, index, itemLink, staticbuyoutAmount) + StaticPopup_Show("CONFIRM_BUY_ITEM"..popupsCount) + end + staticOffset = staticOffset + 1 + end + elseif buyoutAmount == '+' then + local maxStack = select(8,GetItemInfo(itemID)) + local heldAmount = maxStack - GetItemCount(itemID) + BuyMerchantItem(index, heldAmount > 0 and heldAmount or maxStack) + else + local amount1, amount2 = match(buyoutAmount, '(%d*)+(%d*)') + local buyoutAmountVal = tonumber(amount1 or amount2) + if buyoutAmountVal then + local topAmount = buyoutAmountVal - GetItemCount(itemID) + if topAmount > 0 then + BuyMerchantItem(index, topAmount) + end + else + BuyMerchantItem(index, tonumber(buyoutAmount)) + end + end + end + index = index + 1 + itemLink = GetMerchantItemLink(index) + end +end + +local function probeMerchantStuff(collectionMethod) + local index = 1 + local itemLink = GetMerchantItemLink(index) + while itemLink do + local itemID = tonumber(match(itemLink, "item:(%d+)")) + local buyoutAmount = collectionMethod(getItemDetails(itemID)) + if buyoutAmount then + return true + else + index = index + 1 + itemLink = GetMerchantItemLink(index) + end + end +end + P["Extras"]["blizzard"][modName] = { ["ConfirmRolls"] = { ["enabled"] = false, }, - ["PickupQuest"] = { + ["AutoPickup"] = { + ["enabled"] = false, + ["collectionMethod"] = "type@"..select(12,GetAuctionItemClasses()), + }, + ["SwiftBuy"] = { ["enabled"] = false, - ["itemsToPickUp"] = {}, + ["modifier"] = "Alt", + ["selectedSet"] = 0, + ["defaultCollectionMethod"] = "", + ["defaultFailsafe"] = true, + ["sets"] = {}, }, ["FillDelete"] = { ["enabled"] = false, @@ -38,11 +305,16 @@ P["Extras"]["blizzard"][modName] = { } function mod:LoadConfig(db) + local selectedItemType = 0 + local function selectedSet() return db.SwiftBuy.selectedSet end + local function selectedSetData() + return core:getSelected("blizzard", modName, format("SwiftBuy.sets[%s]", selectedSet() or ""), 0) + end core.blizzard.args[modName] = { type = "group", name = L[modName], get = function(info) return db[info[#info-1]][gsub(info[#info], info[#info-1], '')] end, - set = function(info, value) db[info[#info-1]][gsub(info[#info], info[#info-1], '')] = value mod:Toggle(db) end, + set = function(info, value) db[info[#info-1]][gsub(info[#info], info[#info-1], '')] = value self:Toggle(db) end, disabled = function(info) return info[#info] ~= modName and not match(info[#info], '^enabled') and not db[info[#info-1]].enabled end, args = { ConfirmRolls = { @@ -57,64 +329,256 @@ function mod:LoadConfig(db) }, }, }, - PickupQuest = { + AutoPickup = { type = "group", - name = L["Quest Items and Money"], + name = L["Auto Pickup"], guiInline = true, args = { - enabledPickupQuest = { + enabledAutoPickup = { order = 1, type = "toggle", width = "full", name = core.pluginColor..L["Enable"], - desc = L["Picks up quest items and money automatically."], + desc = L["Picks up items and money automatically."], }, - addItem = { + collectionMethod = { order = 2, type = "input", - name = L["Add Item (by ID)"], - desc = L["More items to pick up automatically."], - get = function() return "" end, - set = function(_, value) - if value and GetItemInfo(value) then - db.PickupQuest.itemsToPickUp[value] = true - local _, link, _, _, _, _, _, _, _, icon = GetItemInfo(value) - core:print('ADDED', '\124T'..gsub(icon, '\124', '\124\124')..':16:16\124t'..link) + multiline = true, + width = "double", + name = L["Collection Method"], + desc = L["Syntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " type@string - matches type,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n".. + " tooltip@string - matches tooltip text.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."], + }, + itemTypeInfo = { + order = 3, + type = "select", + width = "double", + name = L["Available Item Types"], + desc = L["Lists all available item subtypes for each available item type."], + get = function() return selectedItemType end, + set = function(_, value) selectedItemType = value end, + values = function() + local dropdownValues = {[1] = ""} + for _, itemType in ipairs({GetAuctionItemClasses()}) do + tinsert(dropdownValues, itemType) end + return dropdownValues + end, + hidden = function() return not db.AutoPickup.enabled end, + }, + subTypeInfo = { + order = 4, + type = "description", + name = function() + return tconcat({GetAuctionItemSubClasses(selectedItemType-1)}, ", ") end, + hidden = function() return not (db.AutoPickup.enabled and selectedItemType and selectedItemType > 1) end, }, - removeItem = { + }, + }, + SwiftBuy = { + type = "group", + name = L["Swift Buy"], + guiInline = true, + args = { + enabledSwiftBuy = { + order = 1, + type = "toggle", + name = core.pluginColor..L["Enable"], + desc = L["Buys out items automatically."], + }, + modifier = { + order = 2, + type = "select", + name = L["Modifier"], + desc = L["Holding this key while interacting with a merchant buys all items that pass the Auto Buy set method.\n".. + "Hold the modifier key and click the buyout list entry to purchase a single item, regardless of the '@amount' rule."], + values = E.db.Extras.modifiers, + hidden = function() return not db.SwiftBuy.enabled end, + }, + failsafe = { order = 3, + type = "toggle", + name = L["Failsafe"], + desc = L["Enables popup confirmation dialog."], + get = function() return selectedSet() == 0 and db.SwiftBuy.defaultFailsafe or selectedSetData().failsafe end, + set = function(_, value) + if selectedSet() == 0 then + db.SwiftBuy.defaultFailsafe = value + else + selectedSetData().failsafe = value + end + self:Toggle(db) + end, + hidden = function() return not db.SwiftBuy.enabled end, + }, + color = { + order = 4, + type = "color", + name = L["Text Color"], + desc = "", + get = function() return unpack(selectedSet() == 0 and {} or selectedSetData().color or {}) end, + set = function(_, r, g, b) + selectedSetData().color = {r, g, b} + self:Toggle(db) + end, + disabled = function() return selectedSet() == 0 end, + hidden = function() return not db.SwiftBuy.enabled end, + }, + addSet = { + order = 5, + type = "execute", + name = L["Add Set"], + desc = "", + func = function() + tinsert(db.SwiftBuy.sets, 1, + {["failsafe"] = true, + ["title"] = "", + ["collectionMethod"] = "", + ["icon"] = "", + ["color"] = {1,1,1}}) + db.SwiftBuy.selectedSet = 1 + self:Toggle(db) + end, + hidden = function() return not db.SwiftBuy.enabled end, + }, + deleteSet = { + order = 6, + type = "execute", + name = L["Delete Set"], + desc = "", + func = function() + tremove(db.SwiftBuy.sets, selectedSet()) + db.SwiftBuy.selectedSet = 0 + self:Toggle(db) + end, + disabled = function() return selectedSet() == 0 end, + hidden = function() return not db.SwiftBuy.enabled end, + }, + title = { + order = 7, + type = "input", + name = L["Title"], + desc = "", + get = function() return selectedSet() == 0 and L["Auto Buy"] or selectedSetData().title end, + set = function(_, value) selectedSetData().title = value end, + disabled = function() return selectedSet() == 0 end, + hidden = function() return not db.SwiftBuy.enabled end, + }, + selectedSet = { + order = 8, type = "select", - name = L["Remove Item"], + name = L["Select Set"], + desc = "", + get = function() return tostring(selectedSet()) end, + set = function(_, value) db.SwiftBuy.selectedSet = tonumber(value) end, + values = function() + local dropdownValues = {[0] = L["Auto Buy"]} + for i, set in ipairs(db.SwiftBuy.sets) do + dropdownValues[tostring(i)] = set.title + end + return dropdownValues + end, + hidden = function() return not db.SwiftBuy.enabled end, + }, + icon = { + order = 9, + type = "input", + width = "double", + name = L["Icon"], desc = "", - get = function() return "" end, + get = function() return selectedSet() == 0 and "" or selectedSetData().icon end, set = function(_, value) - db.PickupQuest.itemsToPickUp[value] = nil - local _, link, _, _, _, _, _, _, _, icon = GetItemInfo(value) - core:print('REMOVED', '\124T'..gsub(icon, '\124', '\124\124')..':16:16\124t'..link) + selectedSetData().icon = value + self:Toggle(db) end, - values = function() - local values = {} - for id in pairs(db.PickupQuest.itemsToPickUp or {}) do - local name, _, _, _, _, _, _, _, _, icon = GetItemInfo(id) - icon = icon and "|T"..icon..":0|t" or "" - values[id] = format("%s %s (%s)", icon, name or "", id) + hidden = function() return not db.SwiftBuy.enabled end, + }, + collectionMethod = { + order = 10, + type = "input", + multiline = true, + width = "double", + name = L["Collection Method"], + desc = L["Syntax: filter@value@amount\n\n".. + "Available filters:\n".. + " id@number@amount(+)/+ - matches itemID,\n".. + " name@string@amount(+)/+ - matches name,\n".. + " type@string@amount(+)/+ - matches type,\n".. + " subtype@string@amount(+)/+ - matches subtype,\n".. + " ilvl@number@amount(+)/+ - matches ilvl,\n".. + " uselevel@number@amount(+)/+ - matches equip level,\n".. + " quality@number@amount(+)/+ - matches quality,\n".. + " equipslot@number@amount(+)/+ - matches inventorySlotID,\n".. + " maxstack@number@amount(+)/+ - matches stack limit,\n".. + " price@number@amount(+)/+ - matches sell price,\n".. + " tooltip@string@amount(+)/+ - matches tooltip text.\n\n".. + "The optional 'amount' part could be:\n".. + " a number - to purchase a static amount,\n".. + " a + sign - to replenish the existing partial stack or purchase a new one,\n".. + " both (e.g. 5+) - to purchase enough items to reach a specified total (in this case, 5),\n".. + " ommited - defaults to 1.\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols.\n".. + "Standard Lua logic for branching (and/or/parenthesis/etc.) applies.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne."], + get = function() + if selectedSet() == 0 then + return db.SwiftBuy.defaultCollectionMethod + else + return selectedSetData().collectionMethod end - return values end, - sorting = function() - local sortedKeys = {} - for id in pairs(db.PickupQuest.itemsToPickUp or {}) do - tinsert(sortedKeys, id) + set = function(_, value) + if selectedSet() == 0 then + db.SwiftBuy.defaultCollectionMethod = value + else + selectedSetData().collectionMethod = value end - tsort(sortedKeys, function(a, b) - local nameA = GetItemInfo(a) or "" - local nameB = GetItemInfo(b) or "" - return nameA < nameB - end) - return sortedKeys + self:Toggle(db) end, + hidden = function() return not db.SwiftBuy.enabled end, + }, + itemTypeInfo = { + order = 11, + type = "select", + width = "double", + name = L["Available Item Types"], + desc = L["Lists all available item subtypes for each available item type."], + get = function() return selectedItemType end, + set = function(_, value) selectedItemType = value end, + values = function() + local dropdownValues = {[1] = ""} + for _, itemType in ipairs({GetAuctionItemClasses()}) do + tinsert(dropdownValues, itemType) + end + return dropdownValues + end, + hidden = function() return not db.SwiftBuy.enabled end, + }, + subTypeInfo = { + order = 12, + type = "description", + name = function() + return tconcat({GetAuctionItemSubClasses(selectedItemType-1)}, ", ") + end, + hidden = function() return not (db.SwiftBuy.enabled and selectedItemType and selectedItemType > 1) end, }, }, }, @@ -126,7 +590,7 @@ function mod:LoadConfig(db) enabledFillDelete = { type = "toggle", name = core.pluginColor..L["Enable"], - desc = L["Fills 'DELETE' field automatically."], + desc = L["Automatically fills the 'DELETE' field."], }, }, }, @@ -138,7 +602,7 @@ function mod:LoadConfig(db) enabledGossip = { type = "toggle", name = core.pluginColor..L["Enable"], - desc = L["Selects the first gossip option if it's the only one available unless holding a modifier.\nCareful with important event triggers, there's no fail-safe mechanism."], + desc = L["Selects the first gossip option if it's the only one available unless holding a modifier.\nBe careful with important event triggers; there is no fail-safe mechanism."], }, }, }, @@ -183,15 +647,16 @@ function mod:Automations(db) self:Unhook(GossipFrame, 'OnShow') end - if db.PickupQuest.enabled then - local itemsToPickUp = db.PickupQuest.itemsToPickUp or {} + if db.AutoPickup.enabled then + local collectionMethod = updateCollectionMethods(db.AutoPickup.collectionMethod) or function() return end self:RegisterEvent('LOOT_OPENED', function() for i = 1, GetNumLootItems() do local lootLink = GetLootSlotLink(i) if lootLink then local itemID = match(lootLink, 'item:(%d+)') - local itemType = select(6,GetItemInfo(itemID)) - if (itemType and itemType == localizedQuestItemString) or itemsToPickUp[itemID] then + local itemInfo = getItemDetails(itemID) + + if collectionMethod(itemInfo) then LootSlot(i) end elseif i == 1 and select(4,GetLootSlotInfo(i)) == 0 then @@ -203,6 +668,83 @@ function mod:Automations(db) self:UnregisterEvent('LOOT_OPENED') end + if db.SwiftBuy.enabled then + local swiftBuy = db.SwiftBuy + local modifier = swiftBuy.modifier or 'Alt' + local isModDown = modifier == 'ANY' + and function() return IsModifierKeyDown() end + or function() return _G['Is'..modifier..'KeyDown']() end + + methodFuncs = {['autobuy'] = updateCollectionMethods(swiftBuy.defaultCollectionMethod) or function() return end} + + for _, entry in ipairs(swiftBuy.sets) do + local r, g, b = unpack(entry.color or {1,1,1}) + tinsert(methodFuncs, + {updateCollectionMethods(entry.collectionMethod) or function() return end, + (not entry.icon or entry.icon == "") and "" or format("|T%s:12|t", entry.icon), + format("|cff%02x%02x%02x", r * 255, g * 255, b * 255), + }) + end + + if not swiftBuyButton then + swiftBuyButton = CreateFrame("Button", "SwiftBuyButton", MerchantFrame, "UIPanelButtonTemplate") + swiftBuyButton:Size(24) + swiftBuyButton:ClearAllPoints() + swiftBuyButton:Point("TOPLEFT", MerchantFrame, "TOPLEFT", 20, -20) + swiftBuyButton:SetNormalTexture(createTex(swiftBuyButton, "Interface\\GossipFrame\\VendorGossipIcon", 24)) + swiftBuyButton:SetPushedTexture(createTex(swiftBuyButton, "Interface\\GossipFrame\\VendorGossipIcon", 24)) + swiftBuyButton:SetHighlightTexture(createTex(swiftBuyButton, "Interface\\GossipFrame\\VendorGossipIcon", 24)) + swiftBuyButton:SetScript("OnMouseDown", function(self) + self:Point("TOPLEFT", MerchantFrame, "TOPLEFT", 21, -21) + end) + swiftBuyButton:SetScript("OnMouseUp", function(self) + self:Point("TOPLEFT", MerchantFrame, "TOPLEFT", 20, -20) + end) + swiftBuyButton:SetScript("OnEnter", function(self) + for i = 1, #swiftBuy.sets do + if probeMerchantStuff(methodFuncs[i][1]) then + return + end + end + GameTooltip:SetOwner(self, "ANCHOR_RIGHT") + GameTooltip:SetText(BROWSE_NO_RESULTS) + GameTooltip:Show() + end) + swiftBuyButton:SetScript("OnLeave", function() + GameTooltip:Hide() + end) + swiftBuyButton.dropdownMenu = CreateFrame("Frame", "SwiftBuyDropdown", UIParent, "UIDropDownMenuTemplate") + + local function initializeDropdown(self, level) + for i, entry in ipairs(swiftBuy.sets) do + if probeMerchantStuff(methodFuncs[i][1]) then + local info = UIDropDownMenu_CreateInfo() + info.text = format("%s%s%s", methodFuncs[i][2], methodFuncs[i][3], entry.title) + info.menuList = entry.title + info.func = function() + buyMerchantStuff(methodFuncs[i][1], entry.failsafe, isModDown()) + end + UIDropDownMenu_AddButton(info, level) + end + end + end + UIDropDownMenu_Initialize(swiftBuyButton.dropdownMenu, initializeDropdown, "MENU") + + swiftBuyButton:SetScript("OnClick", function(self) + ToggleDropDownMenu(1, nil, self.dropdownMenu, self, 0, 0) + end) + end + self:RegisterEvent('MERCHANT_SHOW', function() + if isModDown() then + buyMerchantStuff(methodFuncs['autobuy'], swiftBuy.defaultFailsafe) + end + end) + elseif swiftBuyButton then + self:UnregisterEvent('MERCHANT_SHOW') + swiftBuyButton:Hide() + swiftBuyButton = nil + end + if db.AcceptQuest.enabled then self:RegisterEvent('QUEST_DETAIL', function() if IsModifierKeyDown() then @@ -216,7 +758,7 @@ function mod:Automations(db) self:RegisterEvent('QUEST_ACCEPT_CONFIRM', function() if IsModifierKeyDown() then ConfirmAcceptQuest() - StaticPopup_Hide("QUEST_ACCEPT_CONFIRM") + StaticPopup_Hide('QUEST_ACCEPT_CONFIRM') end end) self:RegisterEvent('QUEST_PROGRESS', function() @@ -240,17 +782,17 @@ function mod:Automations(db) self:RegisterEvent('CONFIRM_LOOT_ROLL', function(_, id, rollType) if not id or not rollType then return end ConfirmLootRoll(id, rollType) - StaticPopup_Hide("CONFIRM_LOOT_ROLL") + StaticPopup_Hide('CONFIRM_LOOT_ROLL') end) self:RegisterEvent('CONFIRM_DISENCHANT_ROLL', function(_, id, rollType) if not id or not rollType then return end ConfirmLootRoll(id, rollType) - StaticPopup_Hide("CONFIRM_LOOT_ROLL") + StaticPopup_Hide('CONFIRM_LOOT_ROLL') end) self:RegisterEvent('LOOT_BIND_CONFIRM', function(_, id, rollType) if not id or not rollType then return end ConfirmLootRoll(id, rollType) - StaticPopup_Hide("CONFIRM_LOOT_ROLL") + StaticPopup_Hide('CONFIRM_LOOT_ROLL') end) else self:UnregisterEvent('CONFIRM_LOOT_ROLL') diff --git a/Modules/Blizzard/LootStyle.lua b/Modules/Blizzard/LootStyle.lua index 64033af..c5df865 100644 --- a/Modules/Blizzard/LootStyle.lua +++ b/Modules/Blizzard/LootStyle.lua @@ -212,8 +212,8 @@ local rollIcons = { } local rollMsgsProcessed = {} -for type, messages in ipairs(rollMsgs) do - rollMsgsProcessed[type] = {} +for rollType, messages in ipairs(rollMsgs) do + rollMsgsProcessed[rollType] = {} for i, message in ipairs(messages) do local processedMessage = {} local formattedMsg = format(message, 1, 1, 1, 1, 1) @@ -224,14 +224,14 @@ for type, messages in ipairs(rollMsgs) do tinsert(processedMessage, part) end end - rollMsgsProcessed[type][i] = processedMessage + rollMsgsProcessed[rollType][i] = processedMessage end end local function parseEventMsg(msg) msg = gsub(gsub(gsub(msg, '|[tT].+|[tT]', ''), '|%x%x%x%x%x%x%x%x%x.+|[hH]|[rR][%w-]*', ''), '[%s%p%d]', '') - for type, messages in pairs(rollMsgsProcessed) do + for rollType, messages in pairs(rollMsgsProcessed) do for _, processedMessage in ipairs(messages) do local tempMsg = msg local matched = true @@ -243,7 +243,7 @@ local function parseEventMsg(msg) tempMsg = gsub(tempMsg, part, "", 1) end if matched then - return type, tempMsg + return rollType, tempMsg end end end @@ -349,7 +349,7 @@ function mod:LoadConfig() order = 1, type = "toggle", name = core.pluginColor..L["Enable"], - desc = L["Colors online friends' and guildmates' names in some of the messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."], + desc = L["Colors the names of online friends and guildmates in some messages and styles the rolls.\nAlready handled chat bubbles will not get styled before you /reload."], get = function() return db.StyledMsgs.enabled end, set = function(_, value) db.StyledMsgs.enabled = value @@ -439,7 +439,7 @@ function mod:LoadConfig() order = 1, type = "toggle", name = core.pluginColor..L["Enable"], - desc = L["Restyles loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."], + desc = L["Restyles the loot bars.\nRequires 'Loot Roll' (General -> BlizzUI Improvements -> Loot Roll) to be enabled (toggling this module enables it automatically)."], }, sizeIcon = { order = 2, @@ -480,7 +480,7 @@ function mod:StyledMsgs(enable) if not initialized.StyledMsgs then local myname, myclass = E.myname, E.myclass - local playerName = lower(myname) + local mynameLower = lower(myname) local friendOnlineMsgProcessed = gsub(tconcat({split(1, format(gsub(ERR_FRIEND_ONLINE_SS, '[%[%]]',''), 1, 1))}), "|H.+|h", "") local _, playerJoinsGuild = split(1, format(ERR_GUILD_JOIN_S, 1)) local _, part1, part2, part3 = split(1, format(RANDOM_ROLL_RESULT, 1, 1, 1, 1)) @@ -505,7 +505,7 @@ function mod:StyledMsgs(enable) end function mod:GetPlayerRelationship(name) - if name == playerName then + if name == mynameLower then return "self", myclass elseif friendMap[name] then return "friend", friendMap[name] @@ -551,10 +551,10 @@ function mod:StyledMsgs(enable) if isPlayer then _, relClass = "self", myclass - local db = indicators["self"] - if db.indicator ~= "NONE" then - indicatorColor = db.color - indicator = db.indicator + local data = indicators["self"] + if data.indicator ~= "NONE" then + indicatorColor = data.color + indicator = data.indicator end else _, relClass, indicator, indicatorColor = mod:GetPlayerInfo(lower(playerName)) @@ -656,9 +656,9 @@ function mod:StyledMsgs(enable) local strippedMsg, msgMap = stripMsg(msg) local strippedLower = lower(strippedMsg) local replacements = {} - local handledNames = {[playerName] = true} + local handledNames = {[mynameLower] = true} - for _, rep in ipairs(handleFound(strippedMsg, strippedLower, playerName, msgMap, true)) do + for _, rep in ipairs(handleFound(strippedMsg, strippedLower, mynameLower, msgMap, true)) do tinsert(replacements, rep) end @@ -826,8 +826,8 @@ function mod:StyledMsgs(enable) initialized.StyledMsgs = true end - for _, type in ipairs(chatMsgs) do - ChatFrame_AddMessageEventFilter(type, mod.StyledMsgsFilter) + for _, msgType in ipairs(chatMsgs) do + ChatFrame_AddMessageEventFilter(msgType, mod.StyledMsgsFilter) end if not E.db.Extras.blizzard[modName].StyledLootings.enabled then @@ -880,14 +880,14 @@ function mod:StyledMsgs(enable) end if not self:IsHooked(M, "AddChatBubbleName") then - self:RawHook(M, "AddChatBubbleName", function(self, chatBubble, guid, name) + self:RawHook(M, "AddChatBubbleName", function(self, chatBubble, _, name) if not name then return end chatBubble.Name:SetFormattedText("%s", mod:StyleName(name)) end) end elseif initialized.StyledMsgs then - for _, type in ipairs(chatMsgs) do - ChatFrame_RemoveMessageEventFilter(type, mod.StyledMsgsFilter) + for _, msgType in ipairs(chatMsgs) do + ChatFrame_RemoveMessageEventFilter(msgType, mod.StyledMsgsFilter) end if filterApplied then @@ -1236,8 +1236,8 @@ end function mod:Toggle() - for mod, info in pairs(E.db.Extras.blizzard[modName]) do - self[mod](self, info.enabled) + for subMod, info in pairs(E.db.Extras.blizzard[modName]) do + self[subMod](self, core.reload and false or info.enabled) end end diff --git a/Modules/Blizzard/Misc.lua b/Modules/Blizzard/Misc.lua index 1280f51..d77a8a7 100644 --- a/Modules/Blizzard/Misc.lua +++ b/Modules/Blizzard/Misc.lua @@ -153,7 +153,7 @@ function mod:LoadConfig() enabledLessTooltips = { type = "toggle", name = core.pluginColor..L["Enable"], - desc = L["Unless holding a modifier, hovering units, items, and spells draws no tooltip.\nModifies cursor tooltips only."], + desc = L["Tooltips will not display when hovering over units, items, and spells unless a modifier is held.\nModifies cursor tooltips only."], }, }, }, @@ -218,11 +218,11 @@ function mod:PlayerPings(enable) self.PlayerPingFrame = self:CreatePingFrame() initialized.PlayerPings = true end - self:RegisterEvent("MINIMAP_PING", function(_, _, unitTarget, x, y) - mod:ShowPlayerPing(UnitName(unitTarget)) - end, x, y) + self:RegisterEvent("MINIMAP_PING", function(_, unit) + self:ShowPlayerPing(UnitName(unit)) + end) elseif initialized.PlayerPings then - mod.PlayerPingFrame.PingText:Hide() + self.PlayerPingFrame.PingText:Hide() self:UnregisterEvent("MINIMAP_PING") end end @@ -312,6 +312,7 @@ end function mod:HideErrors(enable) if enable then + local db = E.db.Extras.blizzard[modName].HideErrors UIErrorsFrame:SetScript('OnEvent', function (self, event, err, ...) if event == 'UI_ERROR_MESSAGE' then if err == ERR_INV_FULL or @@ -328,11 +329,8 @@ function mod:HideErrors(enable) err:find(format(ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S, ".+")) then return OrigErrHandler(self, event, err, ...) end - end - if E.db.Extras.blizzard[modName].HideErrors.showQuestUpdates then - if event == 'UI_INFO_MESSAGE' then - return OrigErrHandler(self, event, err, ...) - end + elseif db.showQuestUpdates and event == 'UI_INFO_MESSAGE' then + return OrigErrHandler(self, event, err, ...) end end) else @@ -374,8 +372,8 @@ end function mod:Toggle() - for mod, info in pairs(E.db.Extras.blizzard[modName]) do - self[mod](self, info.enabled) + for subMod, info in pairs(E.db.Extras.blizzard[modName]) do + self[subMod](self, core.reload and false or info.enabled) end end @@ -384,4 +382,4 @@ function mod:InitializeCallback() mod:Toggle() end -core.modules[modName] = mod.InitializeCallback +core.modules[modName] = mod.InitializeCallback \ No newline at end of file diff --git a/Modules/General/Bags.lua b/Modules/General/Bags.lua index a8acfbc..291ac44 100644 --- a/Modules/General/Bags.lua +++ b/Modules/General/Bags.lua @@ -7,46 +7,53 @@ local LSM = E.Libs.LSM local LibProcessable = LibStub("LibProcessable") local modName = mod:GetName() -local buttonMap, lastScan, equippedBags, tooltipInfo = {}, {}, {}, {} -local globalSort, initialized = {}, {} -local incombat = false +local buttonMap, itemCounts, tooltipInfo = {}, {}, {} +local equipmentSets = {} +local activeFilters = {} +local removingBag = false +local initialized = {} + mod.localhooks = {} +mod.buttonMap = buttonMap +mod.itemCounts = itemCounts local prospectingSpellID = 31252 local disenchantingSpellID = 13262 local millingSpellID = 51005 local lockpickingSpellID = 1804 -local _G, unpack, pairs, ipairs, select, print = _G, unpack, pairs, ipairs, select, print +local _G, unpack, pairs, ipairs, select, print, next = _G, unpack, pairs, ipairs, select, print, next local tonumber, tostring, loadstring, pcall, type = tonumber, tostring, loadstring, pcall, type -local tinsert, tremove, tsort = table.insert, table.remove, table.sort -local min, max, floor, ceil, huge = min, max, floor, ceil, math.huge -local find, format, lower, match, gsub = string.find, string.format, string.lower, string.match, string.gsub +local tinsert, tremove, twipe, tsort, tconcat = table.insert, table.remove, table.wipe, table.sort, table.concat +local min, max, floor, ceil, huge, pi = min, max, floor, ceil, math.huge, math.pi +local find, format, lower, match, gmatch, gsub = string.find, string.format, string.lower, string.match, string.gmatch, string.gsub local UIParent, GameTooltip_Hide, InCombatLockdown, UnitFactionGroup = UIParent, GameTooltip_Hide, InCombatLockdown, UnitFactionGroup local GetItemInfo, GetInventoryItemTexture, GetBagName = GetItemInfo, GetInventoryItemTexture, GetBagName -local BankButtonIDToInvSlotID, ContainerIDToInventoryID, GetContainerItemID = BankButtonIDToInvSlotID, ContainerIDToInventoryID, GetContainerItemID +local GetItemCount, GetCursorInfo = GetItemCount, GetCursorInfo +local ContainerIDToInventoryID, GetContainerItemID = ContainerIDToInventoryID, GetContainerItemID local GetContainerNumSlots, GetContainerNumFreeSlots = GetContainerNumSlots, GetContainerNumFreeSlots local GetCurrencyListInfo, GetCurrencyListSize, GetItemQualityColor = GetCurrencyListInfo, GetCurrencyListSize, GetItemQualityColor local StackSplitFrame, StackSplitOkayButton = StackSplitFrame, StackSplitOkayButton local StackSplitRightButton, StackSplitLeftButton = StackSplitRightButton, StackSplitLeftButton -local BuyMerchantItem, GetAuctionItemClasses, ClearCursor = BuyMerchantItem, GetAuctionItemClasses, ClearCursor -local IsModifierKeyDown, GetSpellInfo, GetSpellLink, GetKeyRingSize = IsModifierKeyDown, GetSpellInfo, GetSpellLink, GetKeyRingSize +local BuyMerchantItem, GetMerchantItemLink = BuyMerchantItem, GetMerchantItemLink +local GetAuctionItemClasses, GetAuctionItemSubClasses = GetAuctionItemClasses, GetAuctionItemSubClasses +local GetSpellInfo, GetSpellLink, GetKeyRingSize = GetSpellInfo, GetSpellLink, GetKeyRingSize +local IsModifierKeyDown, IsAltKeyDown, IsShiftKeyDown, ClearCursor = IsModifierKeyDown, IsAltKeyDown, IsShiftKeyDown, ClearCursor +local GetNumEquipmentSets, GetEquipmentSetInfo, GetEquipmentSetLocations = GetNumEquipmentSets, GetEquipmentSetInfo, GetEquipmentSetLocations +local EquipmentManager_UnpackLocation, GetInventoryItemID = EquipmentManager_UnpackLocation, GetInventoryItemID local ERR_NOT_IN_COMBAT, ERR_INVALID_ITEM_TARGET, ERR_SPLIT_FAILED = ERR_NOT_IN_COMBAT, ERR_INVALID_ITEM_TARGET, ERR_SPLIT_FAILED local CURRENCY, NUM_BAG_SLOTS, EMPTY = CURRENCY, NUM_BAG_SLOTS, EMPTY +local NUM_FREE_SLOTS, FILTERS = NUM_FREE_SLOTS, FILTERS +local NUM_BANKBAGSLOTS = NUM_BANKBAGSLOTS local B_PickupItem, B_GetItemID, B_GetItemInfo = B.PickupItem, B.GetItemID, B.GetItemInfo local B_GetContainerFrame, B_SplitItem = B.GetContainerFrame, B.SplitItem -local E_Delay, E_Flash, E_StopFlash = E.Delay, E.Flash, E.StopFlash -local updatePending = false +local holderTT = CreateFrame("GameTooltip", "ExtrasBags_DescTooltip", nil, "GameTooltipTemplate") local scanner = CreateFrame("GameTooltip", "ExtrasBags_ScanningTooltip", nil, "GameTooltipTemplate") scanner:SetOwner(WorldFrame, "ANCHOR_NONE") local Weapon, Armor, Container, Consumable, Glyph, TradeGoods, Projectile, Quiver, Recipe, Gem, Miscellaneous, Quest = GetAuctionItemClasses() -local _, _, Leather = GetAuctionItemSubClasses(2) -local _, _, _, MetalStone, _, Herb, Enchanting, _, Parts = GetAuctionItemSubClasses(6) -local Arrow, Bullet = GetAuctionItemSubClasses(7) -local Inscription = select(12,GetAuctionItemSubClasses(9)) local itemTypePriority = { [Weapon] = 1, @@ -109,58 +116,11 @@ local inventorySlotIDs = { ["INVTYPE_RELIC"] = 18, } -local filter = { - id = function(item) return item.id end, - type = function(item) return item.type and lower(gsub(gsub(item.type, '%s+', ''), '%p+', '')) end, - subtype = function(item) return item.subType and lower(gsub(gsub(item.subType, '%s+', ''), '%p+', '')) end, - ilvl = function(item) return item.ilvl end, - uselevel = function(item) return item.useLevel end, - quality = function(item) return item.quality end, - name = function(item) return item.name and lower(gsub(gsub(item.name, '%s+', ''), '%p+', '')) end, - equipslot = function(item) return inventorySlotIDs[item.equipSlot] end, - maxstack = function(item) return item.maxStack end, - price = function(item) return item.sellPrice end, - tooltip = function(item) return tooltipInfo[item.id] end, -} - -local specialBagFilters = { - [1] = "subtype@"..Arrow, -- Quiver - [2] = "subtype@"..Bullet, -- Ammo Pouch - [4] = "id@6265", -- Soul Bag - [8] = "subtype@"..Leather, -- Leatherworking Bag - [16] = "subtype@"..Inscription, -- Inscription Bag - [32] = "subtype@"..Herb, -- Herb Bag - [64] = "subtype@"..Enchanting, -- Enchanting Bag - [128] = "subtype@"..Parts, -- Engineering Bag - [512] = "type@"..Gem, -- Gem Bag - [1024] = "subtype@"..gsub(gsub(MetalStone, '%s+', ''), '%p+', ''), -- Mining Bag -} - - -local function getItemTooltipText(bagID, slotID) - scanner:ClearLines() - if bagID == -1 then - scanner:SetInventoryItem("player", BankButtonIDToInvSlotID(slotID)) - else - scanner:SetBagItem(bagID, slotID) - end - - local tooltipText = '' - for i = 2, scanner:NumLines() do - local left = _G["ExtrasBags_ScanningTooltipTextLeft"..i]:GetText() - local right = _G["ExtrasBags_ScanningTooltipTextRight"..i]:GetText() - - tooltipText = tooltipText .. (left or '') - tooltipText = tooltipText .. (right or '') - end - - return tooltipText -end local function getItemDetails(bagID, slotID, itemID) if not itemID then return nil end - local itemName, _, quality, itemLevel, useLevel, itemType, itemSubType, maxStack, equipSlot, _, sellPrice = GetItemInfo(itemID) + local itemName, itemLink, quality, itemLevel, useLevel, itemType, itemSubType, maxStack, equipSlot, _, sellPrice = GetItemInfo(itemID) local stackCount = select(2, B_GetItemInfo(nil, bagID, slotID)) return { @@ -175,14 +135,65 @@ local function getItemDetails(bagID, slotID, itemID) stackCount = stackCount, maxStack = maxStack, sellPrice = sellPrice, + itemLink = itemLink, + bagID = bagID, + slotID = slotID, } end +local filter = { + id = function(item) return item.id end, + type = function(item) return item.type and lower(gsub(item.type, '[%s%p]+', '')) end, + subtype = function(item) return item.subType and lower(gsub(item.subType, '[%s%p]+', '')) end, + ilvl = function(item) return item.ilvl end, + uselevel = function(item) return item.useLevel end, + quality = function(item) return item.quality end, + name = function(item) return item.name and lower(gsub(item.name, '[%s%p]+', '')) end, + equipslot = function(item) return inventorySlotIDs[item.equipSlot] end, + maxstack = function(item) return item.maxStack end, + price = function(item) return item.sellPrice end, + tooltip = function(item) + if tooltipInfo[item.id] then + return tooltipInfo[item.id] + else + scanner:ClearLines() + scanner:SetHyperlink(item.itemLink) + + local tooltipText = '' + for i = 2, scanner:NumLines() do + local left = _G["ExtrasBags_ScanningTooltipTextLeft"..i]:GetText() + local right = _G["ExtrasBags_ScanningTooltipTextRight"..i]:GetText() + + tooltipText = tooltipText .. (left or '') + tooltipText = tooltipText .. (right or '') + end + tooltipText = lower(gsub(tooltipText, '[%s%p]+', '')) + tooltipInfo[item.id] = tooltipText + return tooltipText + end + end, + set = function(item) + local sets = {} + local setsInfo = equipmentSets[item.id] + if setsInfo then + for _, equipmentSet in ipairs(setsInfo) do + local _, bank, bags, setSlotID, setBagID = + EquipmentManager_UnpackLocation(GetEquipmentSetLocations(equipmentSet.setName)[equipmentSet.equipmentSlot]) + if (bags and item.slotID == setSlotID and item.bagID == setBagID) or (bank and setSlotID - 39 == item.slotID) then + sets[equipmentSet.setNameClean] = true + end + end + end + return sets + end, +} + + local function defaultSort(a, b) local bagIDA, slotIDA, bagIDB, slotIDB = a.bagID, a.slotID, b.bagID, b.slotID - local itemIDA, itemIDB = B_GetItemID(nil, bagIDA, slotIDA), B_GetItemID(nil, bagIDB, slotIDB) + local itemIDA, itemIDB = a.itemID or B_GetItemID(nil, bagIDA, slotIDA), b.itemID or B_GetItemID(nil, bagIDB, slotIDB) - if not itemIDA and not itemIDB then return false end + if not itemIDA and not itemIDB then return (bagIDA * 100) + slotIDA < (bagIDB * 100) + slotIDB end if not itemIDA then return false end if not itemIDB then return true end @@ -215,38 +226,68 @@ local function defaultSort(a, b) return itemA.stackCount > itemB.stackCount end +local function updateSetsInfo() + twipe(equipmentSets) + for i = 1, GetNumEquipmentSets() do + local setName = GetEquipmentSetInfo(i) + if setName then + local locations = GetEquipmentSetLocations(setName) + if locations then + for slotID, location in pairs(locations) do + if location then + local itemID + local player, bank, bags, slot, bag = EquipmentManager_UnpackLocation(location) + if bags then + itemID = B_GetItemID(nil, bag, slot) + elseif bank then + itemID = B_GetItemID(nil, -1, slot - 39) + elseif player then + itemID = GetInventoryItemID("player", slot) + end + if itemID then + if not equipmentSets[itemID] then + equipmentSets[itemID] = {} + end + tinsert(equipmentSets[itemID], {setName = setName, + setNameClean = lower(gsub(setName, '[%s%p]+', '')), + equipmentSlot = slotID}) + end + end + end + end + end + end +end local function formatCondition(filterName, operator, value) - if filterName == "name" then - return format('string.match(string.lower(filterFuncs.%s(item) or ""), "%s")', filterName, lower(value)) + if filterName == "set" then + return format('filterFuncs.%s(item)[%q]', filterName, lower(value)) + elseif filterName == "name" or filterName == "tooltip" then + return format('find(filterFuncs.%s(item) or "", "%s", 1, true)', filterName, lower(value)) else if tonumber(value) then return format('(filterFuncs.%s(item) and filterFuncs.%s(item) %s %s or false)', filterName, filterName, operator, value) elseif operator == '~=' then - return format('not string.match(string.lower(filterFuncs.%s(item) or ""), "%s")', filterName, lower(value)) + return format('not find(filterFuncs.%s(item) or "", "%s", 1, true)', filterName, lower(value)) else - return format('string.match(string.lower(filterFuncs.%s(item) or ""), "%s")', filterName, lower(value)) + return format('find(filterFuncs.%s(item) or "", "%s", 1, true)', filterName, lower(value)) end end end local function parseCollectionString(conditions) local formattedConditions = conditions - local startIndex = 1 - while true do - local conditionStart, conditionEnd = find(formattedConditions, '%S+@[<>=~!]*%S+', startIndex) - if not conditionStart then break end + for condition in gmatch(formattedConditions, '%S+@[<>=~!]*%S+') do + local pair, filterName, operator, value = match(condition, '(([^%s%p]*)@(%p*)([^%s%p]*))') - local pair, filterName, operator, value = match(formattedConditions:sub(conditionStart, conditionEnd), '(([^%s%p]*)@(%p*)([^%s%p]*))') if filterName and filter[filterName] and value then operator = operator ~= '' and operator or '==' local formattedCondition = formatCondition(filterName, operator, value) formattedConditions = gsub(formattedConditions, pair, formattedCondition) - startIndex = conditionStart + #formattedCondition else - core:print('FORMATTING', L["Bags"]) - return + core:print('FORMATTING', L["Bags"]) + return end end @@ -270,6 +311,7 @@ local function updateCollectionMethods(section) local luaFunction, errorMsg = loadstring(parsedString) if luaFunction then + setfenv(luaFunction, { find = string.find }) local success, customFuncGenerator = pcall(luaFunction) if not success then core:print('FAIL', L["Bags"], customFuncGenerator) @@ -318,69 +360,338 @@ local function updateSortMethods(section) end -local function updateLayouts() - E_Delay(nil, 0.1, function() - for _, isBank in ipairs({false, true}) do - local f = B_GetContainerFrame(nil, isBank) - if f and f.currentLayout then - local updatedSections = {} - if not incombat and updatePending then - updatedSections = mod:ApplyBagChanges(f, mod:ScanBags(f)) - updatePending = false +local function toggleLayoutMode(f, toggle) + if toggle then + for _, section in ipairs(f.currentLayout.sections) do + local sectionFrame = section.frame + if not sectionFrame.sizeCrosshairs then + sectionFrame.sizeCrosshairs = CreateFrame("Frame", '$parentSizeCrosshairs', sectionFrame) + sectionFrame.sizeCrosshairs:Point("CENTER", sectionFrame, "RIGHT") + sectionFrame.sizeCrosshairs:Size(30) + sectionFrame.sizeCrosshairs:EnableMouse(true) + sectionFrame.sizeCrosshairs:RegisterForDrag("LeftButton") + sectionFrame.sizeCrosshairs:SetMovable(true) + sectionFrame.sizeCrosshairs:SetClampedToScreen(true) + + sectionFrame.sizeCrosshairs.tex = sectionFrame.sizeCrosshairs:CreateTexture(nil, "BACKGROUND") + sectionFrame.sizeCrosshairs.tex:SetAllPoints() + sectionFrame.sizeCrosshairs.tex:Size(20) + sectionFrame.sizeCrosshairs.tex:SetTexture(E.Media.Textures.Spark) + sectionFrame.sizeCrosshairs.tex:SetAlpha(0) + + sectionFrame.sizeCrosshairs.tex1 = sectionFrame.sizeCrosshairs:CreateTexture(nil, "ARTWORK") + sectionFrame.sizeCrosshairs.tex1:Point("CENTER", sectionFrame.sizeCrosshairs, "CENTER", 5, 0) + sectionFrame.sizeCrosshairs.tex1:Size(20) + sectionFrame.sizeCrosshairs.tex1:SetRotation(-pi/2) + sectionFrame.sizeCrosshairs.tex1:SetTexture(E.Media.Arrows.ArrowUp) + + sectionFrame.sizeCrosshairs.tex2 = sectionFrame.sizeCrosshairs:CreateTexture(nil, "ARTWORK") + sectionFrame.sizeCrosshairs.tex2:Point("CENTER", sectionFrame.sizeCrosshairs, "CENTER", -5, 0) + sectionFrame.sizeCrosshairs.tex2:Size(20) + sectionFrame.sizeCrosshairs.tex2:SetRotation(pi/2) + sectionFrame.sizeCrosshairs.tex2:SetTexture(E.Media.Arrows.ArrowUp) + + sectionFrame.sizeCrosshairs:SetScript("OnEnter", function(self) + E:UIFrameFadeIn(self.tex, 0.2, self.tex:GetAlpha(), 0.5) + end) + sectionFrame.sizeCrosshairs:SetScript("OnLeave", function(self) + E:UIFrameFadeOut(self.tex, 0.2, self.tex:GetAlpha(), 0) + end) + sectionFrame.sizeCrosshairs:SetScript("OnMouseDown", function() + sectionFrame.header.highlight.tex:SetAlpha(0.8) + sectionFrame.header.highlight.tex2:SetAlpha(0) + E:UIFrameFadeIn(sectionFrame.header.highlight, 0.2, sectionFrame.header.highlight:GetAlpha(), 1) + end) + sectionFrame.sizeCrosshairs:SetScript("OnMouseUp", function() + sectionFrame.header.highlight.tex:SetAlpha(0.1) + sectionFrame.header.highlight.tex2:SetAlpha(1) + E:UIFrameFadeOut(sectionFrame.header.highlight, 0.2, sectionFrame.header.highlight:GetAlpha(), 0) + end) + sectionFrame.sizeCrosshairs:SetScript("OnDragStop", function(self) + self.tex:SetVertexColor(1, 1, 1) + self:StopMovingOrSizing() + self:SetScript("OnUpdate", nil) + self:ClearAllPoints() + self:Point("CENTER", sectionFrame, "RIGHT") + sectionFrame.header.highlight.tex:SetAlpha(0.1) + sectionFrame.header.highlight.tex2:SetAlpha(1) + E:UIFrameFadeOut(sectionFrame.header.highlight, 0.2, sectionFrame.header.highlight:GetAlpha(), 0) + end) + sectionFrame.sizeCrosshairs:SetScript("OnDragStart", function(self) + local layout = f.currentLayout + local buttonSize, buttonSpacing = layout.buttonSize, layout.buttonSpacing + local numColumns, maxButtons = layout.numColumns, layout.maxButtons + local buttonOffset = buttonSize + buttonSpacing + self.tex:SetVertexColor(0, 0.5, 0) + self:StartMoving() + self.x = select(4, self:GetPoint()) + self.existingColumns = section.db.numColumns + self:SetScript("OnUpdate", function() + self.totalDragged = (select(4, self:GetPoint()) - self.x) + self.numColumns = self.totalDragged < 0 and floor(self.totalDragged / (buttonSize + buttonSpacing)) + or ceil(self.totalDragged / (buttonSize + buttonSpacing)) + local newNumColumns = max(1, min(numColumns, self.existingColumns + self.numColumns)) + sectionFrame:Width(newNumColumns * (buttonSize + buttonSpacing) - buttonSpacing) + section.db.numColumns = newNumColumns + twipe(section.db.buttonPositions) + for j = 1, maxButtons do + local col = (j - 1) % newNumColumns + local row = floor((j - 1) / newNumColumns) + tinsert(section.db.buttonPositions, {col * buttonOffset, -row * buttonOffset}) + end + mod:UpdateSection(f, 1, section, numColumns, buttonSize, buttonSpacing, true) + end) + end) + end + sectionFrame.sizeCrosshairs:Show() + sectionFrame.sizeCrosshairs:SetFrameLevel(10000) + end + else + for _, section in ipairs(f.currentLayout.sections) do + if section.frame.sizeCrosshairs then + section.frame.sizeCrosshairs:Hide() + end + end + end +end + +local function updateEmptyButtonCount(f, update) + local emptyButton = f.emptyButton + if update then + if emptyButton.emptySlotsSelection == 0 then + local empty = 0 + for _ in pairs(buttonMap[f]) do + empty = empty + 1 + end + emptyButton.emptySlotsText:SetText(empty) + emptyButton.emptySlotsText:SetTextColor(1,1,1) + else + for _, section in ipairs(f.currentLayout.sections) do + if section.db.bagID == emptyButton.emptySlotsSelection then + emptyButton.emptySlotsText:SetTextColor(unpack(section.db.title.color)) + emptyButton.emptySlotsText:SetText(GetContainerNumFreeSlots(emptyButton.emptySlotsSelection)) + return end - local buttonSize = isBank and B.db.bankSize or B.db.bagSize + end + emptyButton.emptySlotsText:SetTextColor(1,1,1) + emptyButton.emptySlotsText:SetText(GetContainerNumFreeSlots(emptyButton.emptySlotsSelection)) + end + else + local nextBagSlots, color + for _, bagID in ipairs(f.BagIDs) do + local bag = bagID ~= emptyButton.emptySlotsSelection and f.Bags[bagID] + if bag and bag.numSlots > 0 and bag.type and bag.type ~= 0 then + nextBagSlots = GetContainerNumFreeSlots(bagID) + emptyButton.emptySlotsSelection = bagID for _, section in ipairs(f.currentLayout.sections) do - if incombat then - section.frame.minimized = false - else - section.frame.minimized = section.db.minimized + if section.db.bagID == bagID then + color = section.db.title.color end - mod:ToggleMinimizeSection(f, section, buttonSize, incombat, updatedSections) end + break end end - end) + if nextBagSlots then + emptyButton.emptySlotsText:SetText(nextBagSlots) + emptyButton.emptySlotsText:SetTextColor(unpack(color or {1,1,1})) + else + local empty = 0 + for _ in pairs(buttonMap[f]) do + empty = empty + 1 + end + emptyButton.emptySlotsText:SetText(empty) + emptyButton.emptySlotsText:SetTextColor(1,1,1) + emptyButton.emptySlotsSelection = 0 + end + end +end + +local function showEmptyButtonTT(f) + local total, empty = 0, 0 + for _, bagID in ipairs(f.BagIDs) do + local bag = f.Bags[bagID] + if bag and bag.numSlots > 0 then + empty = empty + GetContainerNumFreeSlots(bagID) + total = total + bag.numSlots + end + end + GameTooltip:SetOwner(f.emptyButton) + GameTooltip:ClearLines() + if not f.emptyButton.hideHints then + GameTooltip:AddLine(L["Click: Toggle layout mode."]) + GameTooltip:AddLine(L["Alt-Click: Re-evaluate all items."]) + GameTooltip:AddLine(L["Shift-Alt-Click: Toggle these hints."]) + GameTooltip:AddLine(L["Mouse-Wheel: Navigate between special and normal bags."]) + GameTooltip:AddLine(" ") + GameTooltip:AddLine(L["This button accepts cursor item drops."]) + GameTooltip:AddLine(" ") + end + GameTooltip:AddLine(format(NUM_FREE_SLOTS, empty)) + GameTooltip:Show() +end + +local function handleButton(f, button) + if not button.highlight then + button.highlight = CreateFrame("Frame", nil, button) + button.highlight:SetAllPoints() + + button.highlight.glow = CreateFrame("Frame", nil, button.highlight) + button.highlight.glow:SetAllPoints() + button.highlight.glow.tex = button.highlight.glow:CreateTexture(nil, "OVERLAY") + button.highlight.glow.tex:SetAllPoints() + button.highlight.glow.tex:SetTexture("Interface\\Buttons\\ButtonHilight-Square") + button.highlight.glow.tex:SetBlendMode("ADD") + + button.highlight.pulse = CreateFrame("Frame", nil, button.highlight) + button.highlight.pulse:SetAllPoints() + button.highlight.pulse.tex = button.highlight.pulse:CreateTexture(nil, "OVERLAY") + button.highlight.pulse.tex:SetAllPoints() + button.highlight.pulse.tex:SetTexture("Interface\\Cooldown\\star4") + button.highlight.pulse.tex:SetBlendMode("ADD") + + button.highlight:Hide() + + button.highlight:HookScript("OnShow", function(self) + E:Flash(self.pulse, 1, true) + end) + + button.highlight:HookScript("OnHide", function(self) + E:StopFlash(self.pulse) + end) + end + if not mod:IsHooked(button, "OnEnter") then + mod:SecureHookScript(button, "OnEnter", function(self) + if self.atHeader == 'evaluate' then + E:UIFrameFadeIn(f.emptyButton.highlight, 0.2, f.emptyButton.highlight:GetAlpha(), 1) + showEmptyButtonTT(f) + elseif self.atHeader then + E:UIFrameFadeIn(self.atHeader.frame.header.highlight, 0.2, self.atHeader.frame.header.highlight:GetAlpha(), 1) + else + self.highlight:Hide() + end + end) + end + if not mod:IsHooked(button, "OnLeave") then + mod:SecureHookScript(button, "OnLeave", function(self) + if self.atHeader then + if self.atHeader == 'evaluate' then + E:UIFrameFadeOut(f.emptyButton.highlight, 0.2, f.emptyButton.highlight:GetAlpha(), 0) + f.emptyButton.highlight:SetFrameLevel(999) + GameTooltip_Hide() + else + local header = self.atHeader.frame.header + E:UIFrameFadeOut(self.atHeader.frame.header.highlight, 0.2, self.atHeader.frame.header.highlight:GetAlpha(), 0) + header:SetFrameLevel(999) + if header.prevEmptySlotsSelection then + f.emptyButton.emptySlotsSelection = header.prevEmptySlotsSelection + header.prevEmptySlotsSelection = nil + updateEmptyButtonCount(f, true) + end + end + self:Hide() + self:SetAlpha(1) + self.atHeader = false + end + end) + end + if not mod:IsHooked(button, "OnMouseWheel") then + button:EnableMouseWheel(true) + mod:SecureHookScript(button, "OnMouseWheel", function(self) + if self.atHeader == 'evaluate' then + self:GetScript("OnLeave")(self) + f.emptyButton:GetScript("OnMouseWheel")(f.emptyButton) + end + end) + end + if not mod:IsHooked(button, "OnDragStart") then + mod:SecureHookScript(button, "OnDragStart", function(self) + if GetCursorInfo() then + f.draggedButton = button + f.emptyButton:SetScript("OnUpdate", function(eb) + if not GetCursorInfo() and not button.atHeader then + f.draggedButton = false + eb:SetScript("OnUpdate", nil) + end + end) + end + end) + end end -local function wipeLayout(layout) - if not layout then return end - for _, section in ipairs(layout.sections) do + +local function wipeLayout(f, isBank) + toggleLayoutMode(f) + mod.localhooks[f] = nil + for _, section in ipairs(f.currentLayout.sections) do + for _, button in ipairs(section.buttons) do + if button.highlight then + button.highlight:Hide() + button.highlight = nil + end + if mod:IsHooked(button, "OnEnter") then + mod:Unhook(button, "OnEnter") + end + if mod:IsHooked(button, "OnLeave") then + mod:Unhook(button, "OnLeave") + end + if mod:IsHooked(button, "OnMouseWheel") then + mod:Unhook(button, "OnMouseWheel") + end + if mod:IsHooked(button, "OnDragStart") then + mod:Unhook(button, "OnDragStart") + end + if mod:IsHooked(button, "OnClick") then + mod:Unhook(button, "OnClick") + end + end local frame = section.frame if frame then frame:Hide() - frame.concatenateButton:Hide() - frame.concatenateButton = nil - frame.expandButton:Hide() - frame.expandButton = nil - if frame.title then - frame.title:Hide() - frame.title = nil - end - if section.frame.icon then - frame.icon:Hide() - frame.icon = nil - end - if frame.minimizeHandler then - frame.minimizeHandler:Hide() - frame.minimizeHandler = nil - frame.minimizedLine:Hide() - frame.minimizedLine = nil - end section.frame = nil end end + if f.heldCurrencies then + f.heldCurrencies:Hide() + f.heldCurrencies = nil + end + if f.qualityFilterButton then + f.qualityFilterButton:Hide() + f.qualityFilterButton = nil + end + if f.qualityFilterBar then + for _, bar in ipairs(f.qualityFilterBar) do + bar:Hide() + end + f.qualityFilterBar:Hide() + f.qualityFilterBar = nil + end + f.emptyButton:Hide() + f.emptyButton = nil + f.currentLayout = nil + f.editBox:ClearAllPoints() + if isBank then + f.editBox:Point("BOTTOMLEFT", f.holderFrame, "TOPLEFT", (E.Border * 2) + 18, E.Border * 2 + 2) + f.editBox:Point("RIGHT", f.purchaseBagButton, "LEFT", -5, 0) + else + f.currencyButton:ClearAllPoints() + f.currencyButton:Point("BOTTOM", 0, 4) + f.currencyButton:Point("TOPLEFT", f.holderFrame, "BOTTOMLEFT", 0, 18) + f.currencyButton:Point("TOPRIGHT", f.holderFrame, "BOTTOMRIGHT", 0, 18) + + f.editBox:Point("BOTTOMLEFT", f.holderFrame, "TOPLEFT", (E.Border * 2) + 18, E.Border * 2 + 2) + f.editBox:Point("RIGHT", f.vendorGraysButton, "LEFT", -5, 0) + end end local function runAllScripts(self, event, ...) for _, info in pairs(mod.localhooks) do - for type, script in pairs(info) do - if type == event and script then script(self, ...) end + for handler, script in pairs(info) do + if handler == event and script then script(self, ...) end end end end - P["Extras"]["general"][modName] = { ["EasierProcessing"] = { ["enabled"] = false, @@ -390,22 +701,21 @@ P["Extras"]["general"][modName] = { ["enabled"] = false, ["modifier"] = 'Control', }, - ["BagsExtended"] = { + ["BagsExtendedV2"] = { ["enabled"] = false, ["selectedContainer"] = 'bags', ["containers"] = { ["bags"] = { ["selectedSection"] = 1, - ["sectionSpacing"] = 14, ["iconSpacing"] = 4, ["specialBags"] = {}, ["sections"] = { { - ["length"] = 999, - ["yOffset"] = 0, ["sortMethod"] = '', ["collectionMethod"] = '', ["ignoreList"] = {}, + ["storedPositions"] = {}, + ["sectionSpacing"] = 14, ["icon"] = { ["enabled"] = false, ["texture"] = "Interface\\Icons\\INV_Potion_93", @@ -416,21 +726,16 @@ P["Extras"]["general"][modName] = { ["toText"] = true, ["size"] = 16, }, - ["minimize"] = { - ["enabled"] = false, - ["lineColor"] = { 1, 1, 1, 0.5 }, - }, ["title"] = { - ["enabled"] = false, - ["text"] = "Remaining", + ["text"] = OTHER, ["color"] = { 1, 1, 1 }, ["font"] = "Expressway", ["size"] = 13, ["flags"] = "OUTLINE", ["point"] = "BOTTOMLEFT", - ["relativeTo"] = "TOPLEFT", + ["relativeTo"] = "BOTTOMRIGHT", ["xOffset"] = 0, - ["yOffset"] = 4, + ["yOffset"] = 0, }, }, }, @@ -440,14 +745,110 @@ P["Extras"]["general"][modName] = { } function mod:LoadConfig() + local selectedItemType = 0 local db = E.db.Extras.general[modName] - local function selectedContainer() return db.BagsExtended.selectedContainer end + local function selectedContainer() return db.BagsExtendedV2.selectedContainer end local function selectedContainerData() - return core:getSelected("general", modName, format("BagsExtended.containers[%s]", selectedContainer() or ""), "bags") + return core:getSelected("general", modName, format("BagsExtendedV2.containers[%s]", selectedContainer() or ""), "bags") end local function selectedSection() return selectedContainerData().selectedSection or 1 end local function selectedSectionData() - return core:getSelected("general", modName, format("BagsExtended.containers.%s.sections[%s]", selectedContainer() or "bags", selectedSection() or ""), 1) + return core:getSelected("general", modName, format("BagsExtendedV2.containers.%s.sections[%s]", selectedContainer() or "bags", selectedSection() or ""), 1) + end + local function setupSections(isBank) + local data = selectedContainerData() + local buttonSpacing = data.buttonSpacing or E.Border * 2 + local buttonSize = isBank and B.db.bankSize or B.db.bagSize + local numColumns = floor((isBank and B.db.bankWidth or B.db.bagWidth) / (buttonSize + buttonSpacing)) + local splitCol = floor(numColumns/3) + local splitColumns + if numColumns > 6 then + splitColumns = {splitCol, splitCol, numColumns - splitCol*2} + else + splitColumns = {numColumns, numColumns, numColumns} + end + local icons = { + "Interface\\Icons\\INV_Chest_Chain_15", + "Interface\\Icons\\INV_Sword_27", + "Interface\\Icons\\INV_Jewelcrafting_Gem_32", + "Interface\\Icons\\INV_Engineering_90_Gear", + "Interface\\Icons\\INV_Ammo_Arrow_02", + "Interface\\Icons\\INV_Scroll_06", + "Interface\\Icons\\INV_Potion_51", + "Interface\\Icons\\INV_Letter_05", + "Interface\\Icons\\INV_Misc_Rune_01", + } + for i, sectionType in ipairs({Armor, Weapon, Gem, TradeGoods, Projectile, Recipe, Consumable, Quest, Miscellaneous}) do + tinsert(data.sections, 1, { + ["shouldPopulate"] = true, + ["numColumns"] = i > 3 and splitColumns[i%3+1] or numColumns, + ["sortMethod"] = '', + ["collectionMethod"] = 'type@'..lower(gsub(sectionType, '[%s%p]+', '')), + ["ignoreList"] = {}, + ["storedPositions"] = {}, + ["sectionSpacing"] = 22, + ["title"] = { + ["text"] = sectionType, + ["toIcon"] = true, + ["color"] = { 1, 1, 1 }, + ["font"] = "Expressway", + ["size"] = 13, + ["flags"] = "OUTLINE", + ["point"] = "BOTTOMLEFT", + ["relativeTo"] = "BOTTOMRIGHT", + ["xOffset"] = 0, + ["yOffset"] = 0, + }, + ["icon"] = { + ["enabled"] = true, + ["texture"] = icons[i], + ["point"] = "TOPLEFT", + ["relativeTo"] = "TOPLEFT", + ["xOffset"] = 0, + ["yOffset"] = 2, + ["toText"] = false, + ["size"] = 16, + }, + }) + end + for i = 1, GetNumEquipmentSets() do + local setName = GetEquipmentSetInfo(i) + if setName then + tinsert(data.sections, 1, { + ["shouldPopulate"] = true, + ["numColumns"] = numColumns, + ["sortMethod"] = '', + ["collectionMethod"] = 'set@'..lower(gsub(setName, '[%s%p]+', '')), + ["ignoreList"] = {}, + ["storedPositions"] = {}, + ["sectionSpacing"] = 22, + ["title"] = { + ["text"] = setName, + ["toIcon"] = true, + ["color"] = { 1, 1, 1 }, + ["font"] = "Expressway", + ["size"] = 13, + ["flags"] = "OUTLINE", + ["point"] = "BOTTOMLEFT", + ["relativeTo"] = "BOTTOMRIGHT", + ["xOffset"] = 0, + ["yOffset"] = 0, + }, + ["icon"] = { + ["enabled"] = true, + ["texture"] = select(2,GetEquipmentSetInfo(i)), + ["point"] = "TOPLEFT", + ["relativeTo"] = "TOPLEFT", + ["xOffset"] = 0, + ["yOffset"] = 2, + ["toText"] = false, + ["size"] = 16, + }, + }) + end + end + data.selectedSection = 1 + data.topOffset = 8 end core.general.args[modName] = { type = "group", @@ -466,7 +867,7 @@ function mod:LoadConfig() order = 1, type = "toggle", name = core.pluginColor..L["Enable"], - desc = L["Mod-clicking an item suggest a skill/item to process it."], + desc = L["Mod-clicking an item suggests a skill/item to process it."], }, modifierEasierProcessing = { order = 2, @@ -488,7 +889,7 @@ function mod:LoadConfig() order = 1, type = "toggle", name = core.pluginColor..L["Enable"], - desc = format(L["Holding %s while left-clicking a stack splits it in two; to combine available copies, right-click instead.".. + desc = format(L["Holding %s while left-clicking a stack will split it in two; right-click instead to combine available copies.".. "\n\nAlso modifies the SplitStackFrame to use editbox instead of arrows."], db.SplitStack.modifier), }, modifierSplitStack = { @@ -501,7 +902,7 @@ function mod:LoadConfig() }, }, }, - BagsExtended = { + BagsExtendedV2 = { order = 3, type = "group", name = L["Bags Extended"], @@ -512,21 +913,71 @@ function mod:LoadConfig() type = "toggle", name = core.pluginColor..L["Enable"], desc = L["Extends the bags functionality."], - get = function() return db.BagsExtended.enabled end, - set = function(_, value) db.BagsExtended.enabled = value self:Toggle(db) end, + get = function() return db.BagsExtendedV2.enabled end, + set = function(_, value) db.BagsExtendedV2.enabled = value self:Toggle(db) end, }, - selectedContainer = { + setupSections = { order = 2, + type = "execute", + name = L["Setup Sections"], + desc = L["Adds default sections set to the currently selected container."], + func = function() + setupSections(selectedContainer() == 'bank') + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) + end, + disabled = function() return not db.BagsExtendedV2.enabled end, + }, + buttonSpacing = { + order = 3, + type = "range", + name = L["Button Spacing"], + desc = "", + min = 0, max = 20, step = 1, + get = function() return selectedContainerData().buttonSpacing end, + set = function(_, value) + selectedContainerData().buttonSpacing = value + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) + end, + disabled = function() return not db.BagsExtendedV2.enabled end, + }, + selectedContainer = { + order = 4, type = "select", name = L["Select Container Type"], desc = "", - get = function() return db.BagsExtended.selectedContainer end, - set = function(_, value) db.BagsExtended.selectedContainer = value end, + get = function() return db.BagsExtendedV2.selectedContainer end, + set = function(_, value) db.BagsExtendedV2.selectedContainer = value end, values = { ['bags'] = L['Bags'], ['bank'] = L['Bank'], }, - disabled = function() return not db.BagsExtended.enabled end, + disabled = function() return not db.BagsExtendedV2.enabled end, + }, + topOffset = { + order = 5, + type = "range", + name = L["Top Offset"], + desc = "", + min = 0, max = 60, step = 1, + get = function() return selectedContainerData().topOffset end, + set = function(_, value) + selectedContainerData().topOffset = value + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) + end, + disabled = function() return not db.BagsExtendedV2.enabled end, + }, + bottomOffset = { + order = 6, + type = "range", + name = L["Bottom Offset"], + desc = "", + min = 0, max = 60, step = 1, + get = function() return selectedContainerData().bottomOffset end, + set = function(_, value) + selectedContainerData().bottomOffset = value + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) + end, + disabled = function() return not db.BagsExtendedV2.enabled end, }, }, }, @@ -536,9 +987,12 @@ function mod:LoadConfig() name = L["Settings"], guiInline = true, get = function(info) return selectedSectionData()[info[#info]] end, - set = function(info, value) selectedSectionData()[info[#info]] = value self:UpdateAll() end, - disabled = function() return not db.BagsExtended.enabled end, - hidden = function() return not db.BagsExtended.enabled end, + set = function(info, value) + selectedSectionData()[info[#info]] = value + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) + end, + disabled = function() return not db.BagsExtendedV2.enabled end, + hidden = function() return not db.BagsExtendedV2.enabled end, args = { addSection = { order = 1, @@ -547,13 +1001,12 @@ function mod:LoadConfig() desc = "", func = function() local newSection = { - ["length"] = 8, - ["yOffset"] = 4, ["sortMethod"] = '', ["collectionMethod"] = '', ["ignoreList"] = {}, + ["storedPositions"] = {}, + ["sectionSpacing"] = 14, ["title"] = { - ["enabled"] = true, ["text"] = "New Section", ["toIcon"] = true, ["color"] = { 1, 1, 1 }, @@ -561,9 +1014,9 @@ function mod:LoadConfig() ["size"] = 13, ["flags"] = "OUTLINE", ["point"] = "BOTTOMLEFT", - ["relativeTo"] = "TOPLEFT", + ["relativeTo"] = "BOTTOMRIGHT", ["xOffset"] = 0, - ["yOffset"] = 4, + ["yOffset"] = 0, }, ["icon"] = { ["enabled"] = false, @@ -575,14 +1028,10 @@ function mod:LoadConfig() ["toText"] = false, ["size"] = 16, }, - ["minimize"] = { - ["enabled"] = true, - ["lineColor"] = { 1, 1, 1, 0.5 }, - }, } tinsert(selectedContainerData().sections, 1, newSection) selectedContainerData().selectedSection = 1 - self:UpdateAll() + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}, true) end, }, deleteSection = { @@ -593,47 +1042,29 @@ function mod:LoadConfig() func = function() tremove(selectedContainerData().sections, selectedSection()) selectedContainerData().selectedSection = 1 - self:UpdateAll() - end, - disabled = function() - return not db.BagsExtended.enabled - or selectedSection() == #selectedContainerData().sections - or selectedSectionData().isSpecialBag - end, - }, - length = { - order = 3, - type = "range", - name = L["Section Length"], - desc = "", - min = 1, max = 28, step = 1, - set = function(info, value) - selectedSectionData()[info[#info]] = value - self:UpdateAll() + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) end, disabled = function() - return not db.BagsExtended.enabled + return not db.BagsExtendedV2.enabled or selectedSection() == #selectedContainerData().sections or selectedSectionData().isSpecialBag end, }, - selectedSection = { - order = 4, - type = "select", - name = L["Select Section"], + sectionSpacing = { + order = 3, + type = "range", + name = L["Section Spacing"], desc = "", - get = function() return tostring(selectedSection()) end, - set = function(_, value) selectedContainerData().selectedSection = tonumber(value) end, - values = function() - local dropdownValues = {} - for i, section in ipairs(selectedContainerData().sections) do - dropdownValues[tostring(i)] = section.title.text - end - return dropdownValues + min = 0, max = 40, step = 1, + get = function() return selectedSectionData().sectionSpacing end, + set = function(_, value) + selectedSectionData().sectionSpacing = value + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) end, - }, + disabled = function() return not db.BagsExtendedV2.enabled end, + }, sectionPriority = { - order = 5, + order = 4, type = "input", name = L["Section Priority"], desc = "", @@ -661,64 +1092,94 @@ function mod:LoadConfig() sections[currentIndex] = tempHolder selectedContainerData().selectedSection = 1 end - self:UpdateAll() + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) end, disabled = function() - return not db.BagsExtended.enabled + return not db.BagsExtendedV2.enabled or selectedSection() == #selectedContainerData().sections end, }, - sectionSpacing = { - order = 6, - type = "range", - name = L["Section Spacing"], + selectedSection = { + order = 5, + type = "select", + width = "double", + name = L["Select Section"], desc = "", - min = 0, max = 40, step = 1, - get = function() return selectedContainerData().sectionSpacing end, - set = function(_, value) selectedContainerData().sectionSpacing = value self:UpdateAll() end, - disabled = function() - return not db.BagsExtended.enabled - or selectedSection() == #selectedContainerData().sections + get = function() return tostring(selectedSection()) end, + set = function(_, value) selectedContainerData().selectedSection = tonumber(value) end, + values = function() + local dropdownValues = {} + for i, section in ipairs(selectedContainerData().sections) do + dropdownValues[tostring(i)] = section.title.text + end + return dropdownValues end, - }, + }, collectionMethod = { - order = 7, + order = 6, type = "input", multiline = true, width = "double", name = L["Collection Method"], - desc = L["Handles automated repositioning of the newly received items.".. - "\nSyntax: filter@value\n\n".. - "Available filters:\n".. - "id@number - matches itemID,\n".. - "name@string - matches name,\n".. - "subtype@string - matches subtype,\n".. - "ilvl@number - matches ilvl,\n".. - "uselevel@number - matches equip level,\n".. - "quality@number - matches quality,\n".. - "equipslot@number - matches nventorySlotID,\n".. - "maxstack@number - matches stack limit,\n".. - "price@number - matches sell price,\n\n".. - "tooltip@string - matches tooltip text,\n\n".. - "All string matches are not case sensitive and match only the alphanumeric symbols. Standart lua logic applies. ".. - "Look up GetItemInfo API for more info on filters. ".. - "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. - "Example usage (priest t8 or Shadowmourne):\n".. - "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. - "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. - "The below one notifies of the newly aquired items.\n\n".. - "local icon = GetContainerItemInfo(bagID, slotID)\n".. - "local _, link = GetItemInfo(itemID)\n".. - "icon = gsub(icon, '\\124', '\\124\\124')\n".. - "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. - "print('Item received: ' .. string)"], + desc = L["Handles the automated repositioning of the newly received items.".. + "\nSyntax: filter@value\n\n".. + "Available filters:\n".. + " id@number - matches itemID,\n".. + " name@string - matches name,\n".. + " subtype@string - matches subtype,\n".. + " ilvl@number - matches ilvl,\n".. + " uselevel@number - matches equip level,\n".. + " quality@number - matches quality,\n".. + " equipslot@number - matches inventorySlotID,\n".. + " maxstack@number - matches stack limit,\n".. + " price@number - matches sell price,\n\n".. + " tooltip@string - matches tooltip text,\n\n".. + "All string matches are case-insensitive and match only alphanumeric symbols. Standard Lua logic applies. ".. + "Look up GetItemInfo API for more info on filters. ".. + "Use GetAuctionItemClasses and GetAuctionItemSubClasses (same as on the AH) to get the localized types and subtypes values.\n\n".. + "Example usage (priest t8 or Shadowmourne):\n".. + "(quality@4 and ilvl@>=219 and ilvl@<=245 and subtype@cloth and name@ofSanctification) or name@shadowmourne.\n\n".. + "Accepts custom functions (bagID, slotID, itemID are exposed)\n".. + "The below one notifies of the newly acquired items.\n\n".. + "local icon = GetContainerItemInfo(bagID, slotID)\n".. + "local _, link = GetItemInfo(itemID)\n".. + "icon = gsub(icon, '\\124', '\\124\\124')\n".. + "local string = '\\124T' .. icon .. ':16:16\\124t' .. link\n".. + "print('Item received: ' .. string)"], set = function(info, value) selectedSectionData()[info[#info]] = value - self:UpdateAll() + selectedSectionData().shouldPopulate = true + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) end, + hidden = function() return selectedSectionData().isSpecialBag end, }, - sortMethod = { + itemTypeInfo = { + order = 7, + type = "select", + width = "double", + name = L["Available Item Types"], + desc = L["Lists all available item subtypes for each available item type."], + get = function() return selectedItemType end, + set = function(_, value) selectedItemType = value end, + values = function() + local dropdownValues = {[1] = ""} + for _, itemType in ipairs({GetAuctionItemClasses()}) do + tinsert(dropdownValues, itemType) + end + return dropdownValues + end, + hidden = function() return selectedSectionData().isSpecialBag or selectedContainer() == 'bank' end, + }, + subTypeInfo = { order = 8, + type = "description", + name = function() + return tconcat({GetAuctionItemSubClasses(selectedItemType-1)}, ", ") + end, + hidden = function() return selectedSectionData().isSpecialBag or selectedContainer() == 'bank' end, + }, + sortMethod = { + order = 9, type = "input", multiline = true, width = "double", @@ -731,11 +1192,11 @@ function mod:LoadConfig() "Leave blank to go default."], set = function(info, value) selectedSectionData()[info[#info]] = value - self:UpdateAll() + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) end, }, addItem = { - order = 9, + order = 10, type = "input", width = "double", name = L["Ignore Item (by ID)"], @@ -753,7 +1214,7 @@ function mod:LoadConfig() end, }, removeItem = { - order = 10, + order = 11, type = "select", width = "double", name = L["Remove Ignored"], @@ -768,7 +1229,7 @@ function mod:LoadConfig() texture = gsub(texture, '\124', '\124\124') local string = '\124T' .. texture .. ':16:16\124t' .. link core:print('REMOVED', string) - self:UpdateAll() + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) break end end @@ -786,45 +1247,16 @@ function mod:LoadConfig() }, }, }, - minimize = { + title = { type = "group", - name = L["Minimize"], + name = L["Title"], guiInline = true, - disabled = function() return not db.BagsExtended.enabled end, - hidden = function() return not db.BagsExtended.enabled - or selectedSection() == #selectedContainerData().sections - end, - args = { - enabled = { - order = 1, - type = "toggle", - name = core.pluginColor..L["Enable"], - desc = L["Double-click the title text to minimize the section."], - get = function(info) return selectedSectionData().minimize[info[#info]] end, - set = function(info, value) selectedSectionData().minimize[info[#info]] = value self:UpdateAll() end, - }, - lineColor = { - order = 2, - type = "color", - hasAlpha = true, - name = L["Line Color"], - desc = L["Minimized section's line color."], - get = function(info) return unpack(selectedSectionData().minimize[info[#info]]) end, - set = function(info, r, g, b, a) selectedSectionData().minimize[info[#info]] = { r, g, b, a } self:UpdateAll() end, - disabled = function() return not db.BagsExtended.enabled or not selectedSectionData().minimize.enabled end, - }, - }, - }, - title = { - type = "group", - name = L["Title"], - guiInline = true, - get = function(info) return selectedSectionData().title[info[#info]] end, - set = function(info, value) selectedSectionData().title[info[#info]] = value self:UpdateAll() end, - disabled = function() return not db.BagsExtended.enabled end, - hidden = function() return not db.BagsExtended.enabled - or selectedSection() == #selectedContainerData().sections + get = function(info) return selectedSectionData().title[info[#info]] end, + set = function(info, value) + selectedSectionData().title[info[#info]] = value + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) end, + hidden = function() return not db.BagsExtendedV2.enabled end, args = { color = { order = 0, @@ -832,26 +1264,45 @@ function mod:LoadConfig() name = L["Color"], desc = "", get = function() return unpack(selectedSectionData().title.color) end, - set = function(_, r, g, b) selectedSectionData().title.color = { r, g, b } self:UpdateAll() end, + set = function(_, r, g, b) + selectedSectionData().title.color = { r, g, b } + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) + end, }, toIcon = { order = 1, type = "toggle", name = L["Attach to Icon"], + desc = "", set = function(info, value) selectedSectionData().title[info[#info]] = value selectedSectionData().icon.toText = not value - self:UpdateAll() + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) end, - desc = "", - disabled = function() return not db.BagsExtended.enabled or not selectedSectionData().icon.enabled end, + disabled = function() return not db.BagsExtendedV2.enabled or not selectedSectionData().icon.enabled end, }, text = { order = 2, type = "input", + width = "double", name = L["Text"], desc = "", }, + justify = { + order = 3, + type = "select", + name = L["Justify"], + values = { + ["LEFT"] = L["Left"], + ["CENTER"] = L["Center"], + ["RIGHT"] = L["Right"], + }, + desc = "", + disabled = function() + return not db.BagsExtendedV2.enabled + or (selectedSectionData().icon.enabled and selectedSectionData().icon.toText) + end, + }, size = { order = 3, type = "range", @@ -886,6 +1337,7 @@ function mod:LoadConfig() name = L["Point"], desc = "", values = E.db.Extras.pointOptions, + hidden = function() return not selectedSectionData().icon.enabled end, }, relativeTo = { order = 7, @@ -893,6 +1345,7 @@ function mod:LoadConfig() name = L["Relative Point"], desc = "", values = E.db.Extras.pointOptions, + hidden = function() return not selectedSectionData().icon.enabled end, }, xOffset = { order = 8, @@ -915,11 +1368,11 @@ function mod:LoadConfig() name = L["Icon"], guiInline = true, get = function(info) return selectedSectionData().icon[info[#info]] end, - set = function(info, value) selectedSectionData().icon[info[#info]] = value self:UpdateAll() end, - disabled = function() return not db.BagsExtended.enabled end, - hidden = function() return not db.BagsExtended.enabled - or selectedSection() == #selectedContainerData().sections + set = function(info, value) + selectedSectionData().icon[info[#info]] = value + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) end, + hidden = function() return not db.BagsExtendedV2.enabled end, args = { enabled = { order = 1, @@ -935,7 +1388,7 @@ function mod:LoadConfig() set = function(info, value) selectedSectionData().icon[info[#info]] = value selectedSectionData().title.toIcon = not value - self:UpdateAll() + self:UpdateAll(nil, selectedContainer() == 'bags' and {false} or {true}) end, hidden = function() return not selectedSectionData().icon.enabled end, }, @@ -960,7 +1413,7 @@ function mod:LoadConfig() name = L["Point"], desc = "", values = E.db.Extras.pointOptions, - hidden = function() return not selectedSectionData().icon.enabled end, + hidden = function() return not selectedSectionData().icon.enabled or not selectedSectionData().icon.toText end, }, relativeTo = { order = 6, @@ -968,7 +1421,7 @@ function mod:LoadConfig() name = L["Relative Point"], desc = "", values = E.db.Extras.pointOptions, - hidden = function() return not selectedSectionData().icon.enabled end, + hidden = function() return not selectedSectionData().icon.enabled or not selectedSectionData().icon.toText end, }, xOffset = { order = 7, @@ -990,212 +1443,91 @@ function mod:LoadConfig() }, }, } - if not db.BagsExtended.containers['bank'] then - db.BagsExtended.containers['bank'] = CopyTable(db.BagsExtended.containers['bags']) + if not db.BagsExtendedV2.containers['bank'] then + db.BagsExtendedV2.containers['bank'] = CopyTable(db.BagsExtendedV2.containers['bags']) end end -function mod:UpdateAll(disable) - for _, isBank in pairs({false, true}) do +function mod:UpdateAll(disable, containerType, highlight) + for _, isBank in pairs(containerType or {false, true}) do local f = B_GetContainerFrame(nil, isBank) if f then if disable and f.currentLayout then - wipeLayout(f.currentLayout) + mod.localhooks[f] = nil + wipeLayout(f, isBank) f.holderFrame:ClearAllPoints() f.holderFrame:Point("TOP", f, "TOP", 0, -f.topOffset) f.holderFrame:Point("BOTTOM", f, "BOTTOM", 0, 8) - f.heldCurrencies:Hide() self:HandleSortButton(f, false, isBank) - end - B:Layout(isBank) - end - end -end - -function mod:EvaluateItem(sections, bagID, slotID, itemID) - for _, section in ipairs(sections) do - if section.collectionMethodFunc then - local result = section.collectionMethodFunc(bagID, slotID, itemID) - if result then - for _, button in ipairs(section.buttons) do - if not button.hasItem then - return button.bagID, button.slotID, section - end - end - end - end - end -end - -function mod:HandleControls(f, section, buttonSize) - local sectionFrame, sectionButtons, db = section.frame, section.buttons, section.db - if not sectionFrame.concatenateButton then - sectionFrame.concatenateButton = CreateFrame("Button", "$parentConcatenateButton", sectionFrame, "UIPanelButtonTemplate") - S:HandleButton(sectionFrame.concatenateButton) - sectionFrame.concatenateButton:StyleButton() - sectionFrame.concatenateButton:SetText("-") - sectionFrame.concatenateButton:Show() - sectionFrame.concatenateButton:SetScript("OnHide", function() - sectionFrame.concatenateButton:SetScript('OnUpdate', nil) - sectionFrame.isBeingSorted = false - end) - sectionFrame.concatenateButton:SetScript("OnMouseDown", function() - if incombat or sectionFrame.isBeingSorted or sectionFrame.minimized then return end - sectionFrame.isBeingSorted = true - sectionFrame.expanded = false - local timeElapsed, buttons, stacked, positioned = 0, {} - if not globalSort[f] then E:StartSpinnerFrame(f) end - sectionFrame.concatenateButton:SetScript('OnUpdate', function(self, elapsed) - timeElapsed = timeElapsed + elapsed - if timeElapsed > 0.1 then - if incombat then - sectionFrame.isBeingSorted = false - sectionFrame.concatenateButton:SetScript('OnUpdate', nil) - mod:UpdateSection(f, section, buttonSize) - if not globalSort[f] then mod:ScanBags(f, true) E:StopSpinnerFrame(f) end - return - end - timeElapsed = 0 - if not stacked then - stacked = mod:StackSection(sectionButtons) - if stacked then - local ignoreList = db.ignoreList - local ignored = {} - for i, button in ipairs(sectionButtons) do - local bagID, slotID = button.bagID, button.slotID - local itemID = B_GetItemID(nil, bagID, slotID) - if ignoreList[itemID] then - tinsert(ignored, i) - else - tinsert(buttons, {itemID = itemID, bagID = bagID, slotID = slotID}) + else + mod.localhooks[f] = { + ["OnClick"] = function(self) + if GetCursorInfo() then + f.draggedButton = self + f.emptyButton:SetScript("OnUpdate", function(emptyButton) + if not GetCursorInfo() and not self.atHeader then + f.draggedButton = false + emptyButton:SetScript("OnUpdate", nil) end - end - tsort(buttons, section.sortMethodFunc) - for _, i in ipairs(ignored) do - tinsert(buttons, i, {positioned = true}) - end + end) end - elseif not positioned then - positioned = mod:SortSection(buttons, sectionButtons) - else - sectionFrame.isBeingSorted = false - sectionFrame.concatenateButton:SetScript('OnUpdate', nil) - mod:UpdateSection(f, section, buttonSize) - if not globalSort[f] then mod:ScanBags(f, true) E:StopSpinnerFrame(f) end end - end - end) - end) - end - sectionFrame.concatenateButton:Size(buttonSize / 2, buttonSize / 2) - if not sectionFrame.expandButton then - sectionFrame.expandButton = CreateFrame("Button", "$parentExpandButton", sectionFrame, "UIPanelButtonTemplate") - S:HandleButton(sectionFrame.expandButton) - sectionFrame.expandButton:StyleButton() - sectionFrame.expandButton:SetText("+") - sectionFrame.expandButton:Show() - sectionFrame.expandButton:SetScript("OnMouseDown", function() - if incombat then return end - for i, button in ipairs(sectionButtons) do - if not button:IsShown() and sectionButtons[i-1] then - sectionButtons[i-1].Count:Hide() - end - button:Show() + } + end + B:Layout(isBank) + if highlight then + f.emptyButton.highlight.tex:SetTexture("Interface\\Buttons\\UI-Common-MouseHilight") + f.emptyButton.highlight.tex:SetVertexColor(0, 1, 1) + E:UIFrameFadeIn(f.emptyButton.highlight, 1, f.emptyButton.highlight:GetAlpha(), 1) + E:Delay(1, function() + E:Flash(f.emptyButton.highlight, 1, true) + end) end - sectionFrame.expanded = true - mod:UpdateSection(f, section, buttonSize) - end) - end - sectionFrame.expandButton:Size(buttonSize / 2, buttonSize / 2) - - if db.minimize.enabled then - section.frame.minimized = section.db.minimized - if not sectionFrame.minimizeHandler then - sectionFrame.minimizeHandler = CreateFrame("Button", nil, sectionFrame, "UIPanelButtonTemplate") - sectionFrame.minimizeHandler:SetAllPoints(sectionFrame.title) - sectionFrame.minimizeHandler:SetScript("OnDoubleClick", function() - if incombat then return end - section.db.minimized = not section.db.minimized - section.frame.minimized = section.db.minimized - mod:ToggleMinimizeSection(f, section, buttonSize) - end) - sectionFrame.minimizeHandler:SetAlpha(0) - - sectionFrame.minimizedLine = sectionFrame:CreateTexture(nil, "OVERLAY") - sectionFrame.minimizedLine:Point("TOPLEFT", sectionButtons[1], "TOPLEFT", 0, 0) - sectionFrame.minimizedLine:Point("TOPRIGHT", f.holderFrame, "TOPRIGHT", 0, 0) - sectionFrame.minimizedLine:Height(1) end - sectionFrame.minimizeHandler:Show() - sectionFrame.minimizedLine:SetTexture(unpack(db.minimize.lineColor)) - else - section.frame.minimized = false end end -function mod:ToggleMinimizeSection(f, section, buttonSize, combatUpd, updatedSections) - local sectionFrame = section.frame - if not sectionFrame.minimized then - sectionFrame.concatenateButton:Show() - sectionFrame.expandButton:Show() - if sectionFrame.minimizedLine then - sectionFrame.minimizedLine:Hide() - end - if sectionFrame.title then - sectionFrame.minimizedCount = nil - sectionFrame.title:SetText(section.db.title.text) - end - else - for _, button in ipairs(section.buttons) do button:Hide() button.isHidden = true end - sectionFrame.concatenateButton:Hide() - sectionFrame.expandButton:Hide() - if sectionFrame.minimizedLine then - sectionFrame.minimizedLine:Show() - end +function mod:EvaluateItem(sections, bagID, slotID, itemID) + for _, section in ipairs(sections) do + if (section.collectionMethodFunc and section.collectionMethodFunc(bagID, slotID, itemID)) + or (section.db.isSpecialBag and section.db.bagID == bagID) then + return section, true + end end - if not updatedSections or not updatedSections[section] then - self:UpdateSection(f, section, buttonSize, combatUpd) - self:ResizeFrame(f, buttonSize) - end + return sections[#sections] end -function mod:HandleSortButton(f, enable, isBank) +function mod:HandleSortButton(f, enable, isBank, numColumns, buttonSize, buttonSpacing) if enable then f.sortButton:SetScript("OnClick", nil) f.sortButton:SetScript("OnMouseDown", function() - if incombat then return end - - local sections = {} for _, section in ipairs(f.currentLayout.sections) do - tinsert(sections, section) - end - - tsort(sections, function(a,b) return a.order < b.order end) - - local timeElapsed, index = 0, 1 - local section = sections[index] - globalSort[f] = true - E:StartSpinnerFrame(f) - section.frame.concatenateButton:GetScript("OnMouseDown")() - - f.sortButton:SetScript("OnUpdate", function(self, elapsed) - timeElapsed = timeElapsed + elapsed - if timeElapsed > 0.1 then - if index == #sections then - if not section.frame or not section.frame.isBeingSorted then - f.sortButton:SetScript("OnUpdate", nil) - mod:ScanBags(f, true) - E:StopSpinnerFrame(f) - globalSort[f] = false + if not section.frame.minimized then + local ignoreList = section.db.ignoreList + local sortedButtons = {} + local ignoredButtons = {} + + for i, button in ipairs(section.buttons) do + if ignoreList[button.itemID or B_GetItemID(nil, button.bagID, button.slotID)] then + ignoredButtons[i] = button + else + tinsert(sortedButtons, button) end - elseif not section.frame.isBeingSorted then - index = index + 1 - section = sections[index] - section.frame.concatenateButton:GetScript("OnMouseDown")() end + + tsort(sortedButtons, section.sortMethodFunc) + for i, ignoredButton in pairs(ignoredButtons) do + tinsert(sortedButtons, i, ignoredButton) + end + for i, button in ipairs(sortedButtons) do + section.db.storedPositions[button.bagID..'-'..button.slotID] = i + end + section.buttons = {unpack(sortedButtons)} + + self:UpdateSection(f, 1, section, numColumns, buttonSize, buttonSpacing) end - end) + end end) else f.sortButton:SetScript("OnUpdate", nil) @@ -1212,19 +1544,25 @@ function mod:HandleSortButton(f, enable, isBank) end end -function mod:ConfigureContainer(f, db, maxSectionWidth, numContainerColumns, buttonSize) - wipeLayout(f.currentLayout) - +function mod:ConfigureContainer(f, isBank, db, numColumns, buttonSize, buttonSpacing) local sections = db.sections - local yOffset = -buttonSize/2 - local buttons, specialButtons = {}, {} - local specialBags = {} + local buttons = {} + local specialBags, specialButtons = {}, {} + local processedSections = {} + local minIconLeft = huge + local buttonOffset = buttonSize + buttonSpacing + local maxButtons = 0 + local layoutSections = f.currentLayout and f.currentLayout.sections or {} + + buttonMap[f] = {} for _, bagID in ipairs(f.BagIDs) do - buttonMap[bagID] = {} specialButtons[bagID] = {} - local _, bagType = GetContainerNumFreeSlots(bagID) - if f.Bags[bagID] and f.Bags[bagID].numSlots > 0 then + local bag = f.Bags[bagID] + local bagSlots = bag and bag.numSlots + if bagSlots and bagSlots > 0 then + buttonMap[bagID] = {} + local bagType = bag.type if bagType and bagType ~= 0 then local exists = false for _, section in ipairs(sections) do @@ -1235,59 +1573,109 @@ function mod:ConfigureContainer(f, db, maxSectionWidth, numContainerColumns, but end if not exists or (not db.specialBags[bagID] or db.specialBags[bagID] ~= GetBagName(bagID)) then specialBags[bagID] = { - numSlots = GetContainerNumSlots(bagID), + numSlots = bagSlots, buttons = {}, bagType = bagType, } end - end - for slotID = 1, f.Bags[bagID].numSlots do - local button = f.Bags[bagID][slotID] - if bagType ~= 0 then + for slotID = 1, bagSlots do + local button = bag[slotID] tinsert(specialButtons[bagID], button) - else - tinsert(buttons, button) + handleButton(f, button) end - end + else + for slotID = 1, bagSlots do + local button = bag[slotID] + if button.hasItem then + local itemID = B_GetItemID(nil, bagID, slotID) + itemCounts[itemID] = GetItemCount(itemID) + button.itemID = itemID + tinsert(buttons, button) + else + button.itemID = false + button:Hide() + buttonMap[f][button] = true + end + handleButton(f, button) + end + end + maxButtons = maxButtons + bagSlots end end - self:HandleSortButton(f, true) - - local processedSections = {} - if not f.Sections then f.Sections = {} end - - for i, section in ipairs(sections) do - if section.isSpecialBag then - local bagID = section.bagID - local numSlots, bagType = GetContainerNumFreeSlots(bagID) - if numSlots == 0 or bagType == 0 or (db.specialBags[bagID] and db.specialBags[bagID] ~= GetBagName(bagID)) then - db.specialBags[bagID] = false - tremove(sections, i) - if E.RefreshGUI then E:RefreshGUI() end + self:HandleSortButton(f, true, isBank, numColumns, buttonSize, buttonSpacing) + + if next(layoutSections) then + local cleanup = {} + for i, section in ipairs(sections) do + if section.isSpecialBag then + local bagID = section.bagID + if buttonMap[bagID] then + local numSlots, bagType = GetContainerNumFreeSlots(bagID) + if numSlots == 0 or (not bagType or bagType == 0) or (db.specialBags[bagID] and db.specialBags[bagID] ~= GetBagName(bagID)) then + buttonMap[bagID] = {} + db.specialBags[bagID] = false + tremove(sections, i) + tremove(layoutSections, i) + cleanup[bagID] = true + end + end + end + end + if next(cleanup) then + for _, section in ipairs(layoutSections) do + if section.isSpecialBag and cleanup[section.bagID] then + for _, button in ipairs(section.buttons) do + if button.highlight then + button.highlight:Hide() + button.highlight = nil + end + end + local frame = section.frame + if frame then + frame:Hide() + section.frame = nil + end + end + end + if E.RefreshGUI then E:RefreshGUI() end + end + local currentRowColumns + for i, section in ipairs(layoutSections) do + if i == 1 then + currentRowColumns = section.db.numColumns + section.db.numColumns = min(section.db.numColumns, numColumns) + else + if currentRowColumns + section.db.numColumns <= numColumns then + currentRowColumns = currentRowColumns + section.db.numColumns + else + section.db.numColumns = min(section.db.numColumns, numColumns) + currentRowColumns = section.db.numColumns + end end end + toggleLayoutMode(f, f.emptyButton.showSizing) end for bagID, bagInfo in pairs(specialBags) do local specialSection = { - ["length"] = bagInfo.numSlots, - ["yOffset"] = 4, ["sortMethod"] = '', - ["collectionMethod"] = specialBagFilters[bagInfo.bagType], + ["collectionMethod"] = '', ["ignoreList"] = {}, + ["storedPositions"] = {}, + ["sectionSpacing"] = 14, ["title"] = { ["enabled"] = true, ["text"] = GetBagName(bagID) or "Special Bag", ["toIcon"] = true, - ["color"] = { 1, 1, 1 }, + ["color"] = {unpack(B.ProfessionColors[bagInfo.bagType])}, ["font"] = "Expressway", ["size"] = 13, ["flags"] = "OUTLINE", ["point"] = "BOTTOMLEFT", ["relativeTo"] = "TOPLEFT", ["xOffset"] = 0, - ["yOffset"] = 4, + ["yOffset"] = 0, }, ["icon"] = { ["enabled"] = false, @@ -1299,53 +1687,252 @@ function mod:ConfigureContainer(f, db, maxSectionWidth, numContainerColumns, but ["toText"] = false, ["size"] = 16, }, - ["minimize"] = { - ["enabled"] = true, - ["lineColor"] = { 1, 1, 1, 0.5 }, - }, ["isSpecialBag"] = true, ["bagID"] = bagID, } db.specialBags[bagID] = GetBagName(bagID) tinsert(sections, 1, specialSection) + if f.emptyButton then + f.emptyButton.highlight.tex:SetTexture("Interface\\Buttons\\UI-Common-MouseHilight") + f.emptyButton.highlight.tex:SetVertexColor(0, 1, 1) + E:UIFrameFadeIn(f.emptyButton.highlight, 1, f.emptyButton.highlight:GetAlpha(), 1) + E:Delay(1, function() + E:Flash(f.emptyButton.highlight, 1, true) + end) + end if E.RefreshGUI then E:RefreshGUI() end end for i, section in ipairs(sections) do - local sectionFrame = f.Sections[i] + local sectionFrame = layoutSections[i] and layoutSections[i].frame + + section.buttonPositions = {} + section.numColumns = section.numColumns or numColumns + + local columns = section.numColumns + for j = 1, maxButtons do + local col = (j - 1) % columns + local row = floor((j - 1) / columns) + tinsert(section.buttonPositions, {col * buttonOffset, -row * buttonOffset}) + end if not sectionFrame then sectionFrame = CreateFrame("Frame", "$parentSection"..i, f.holderFrame) - f.Sections[i] = sectionFrame + sectionFrame.header = CreateFrame("Button", "$parentSection"..i.."Header", sectionFrame, "UIPanelButtonTemplate") + sectionFrame.header:SetNormalTexture(nil) + sectionFrame.header:SetPushedTexture(nil) + sectionFrame.header:SetHighlightTexture(nil) + + sectionFrame.header.highlight = CreateFrame("Frame", nil, sectionFrame) + sectionFrame.header.highlight:SetFrameLevel(999) + sectionFrame.header.highlight:SetAllPoints() + sectionFrame.header.highlight:Hide() + + sectionFrame.header.highlight.tex = sectionFrame.header.highlight:CreateTexture(nil, "BACKGROUND") + sectionFrame.header.highlight.tex:Point("TOPLEFT", sectionFrame.header, "TOPLEFT") + sectionFrame.header.highlight.tex:Point("BOTTOMRIGHT", sectionFrame, "BOTTOMRIGHT") + sectionFrame.header.highlight.tex:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") + sectionFrame.header.highlight.tex:SetBlendMode("ADD") + sectionFrame.header.highlight.tex:SetDesaturated(true) + sectionFrame.header.highlight.tex:SetAlpha(0.1) + + sectionFrame.header.highlight.tex2 = sectionFrame.header.highlight:CreateTexture(nil, "BACKGROUND") + sectionFrame.header.highlight.tex2:Point("TOPLEFT", sectionFrame.header, "TOPLEFT") + sectionFrame.header.highlight.tex2:Point("BOTTOMRIGHT", sectionFrame.header, "BOTTOMRIGHT") + sectionFrame.header.highlight.tex2:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") + sectionFrame.header.highlight.tex2:SetBlendMode("ADD") + sectionFrame.header.highlight.tex2:SetVertexColor(0, 0.5, 0) + + sectionFrame.header:SetScript("OnDoubleClick", function() + local layout = f.currentLayout + local currentSection = f.currentLayout.sections[sectionFrame.order] + currentSection.db.minimized = not currentSection.db.minimized + if not currentSection.db.minimized then + sectionFrame.minimizedLine:Hide() + sectionFrame.title:SetText(currentSection.db.title.text) + for _, button in ipairs(currentSection.buttons) do + button.isHidden = false + button:Show() + end + else + sectionFrame.minimizedLine:Show() + sectionFrame:Height(1) + end + self:UpdateSection(f, 1, currentSection, layout.numColumns, layout.buttonSize, layout.buttonSpacing, true) + end) + sectionFrame.header:SetScript("OnReceiveDrag", function() + if f.draggedButton then + f.draggedButton.atHeader = f.currentLayout.sections[sectionFrame.order] + ClearCursor() + f.draggedButton = nil + end + end) + sectionFrame.header:SetScript("OnMouseDown", function() + if f.draggedButton then + f.draggedButton.atHeader = f.currentLayout.sections[sectionFrame.order] + ClearCursor() + f.draggedButton = nil + end + end) + sectionFrame.header:SetScript("OnEnter", function(self) + local cursorInfo = GetCursorInfo() + if cursorInfo == 'item' or cursorInfo == 'merchant' then + local emptyButton + local currentSection = f.currentLayout.sections[sectionFrame.order] + if removingBag then + for button in pairs(buttonMap[f]) do + if button.bagID ~= removingBag then + emptyButton = button + break + end + end + elseif currentSection.db.isSpecialBag then + self.prevEmptySlotsSelection = f.emptyButton.emptySlotsSelection + emptyButton = mod:FindEmpty(nil, f, currentSection.db.bagID) + updateEmptyButtonCount(f, false) + else + emptyButton = next(buttonMap[f]) + end + if emptyButton then + self.highlight.tex2:SetVertexColor(0, 0.5, 0) + self:SetFrameLevel(1) + + emptyButton.atHeader = currentSection + emptyButton:SetAllPoints(self) + emptyButton:SetAlpha(0) + emptyButton:Show() + elseif f.draggedButton then + self.shouldFade = true + self.highlight.tex2:SetVertexColor(0, 0.5, 0) + E:UIFrameFadeIn(self.highlight, 0.2, self.highlight:GetAlpha(), 1) + else + self.shouldFade = true + self.highlight.tex2:SetVertexColor(0.5, 0, 0) + E:UIFrameFadeIn(self.highlight, 0.2, self.highlight:GetAlpha(), 1) + end + end + end) + sectionFrame.header:SetScript("OnLeave", function(self) + if self.shouldFade then + self.shouldFade = false + E:UIFrameFadeOut(self.highlight, 0.2, self.highlight:GetAlpha(), 0) + if self.prevEmptySlotsSelection then + f.emptyButton.emptySlotsSelection = self.prevEmptySlotsSelection + self.prevEmptySlotsSelection = nil + updateEmptyButtonCount(f, true) + end + end + end) + + sectionFrame.minimizedLine = sectionFrame:CreateTexture(nil, "OVERLAY") + sectionFrame.minimizedLine:Point("TOPLEFT", sectionFrame, "TOPLEFT") + sectionFrame.minimizedLine:Point("TOPRIGHT", sectionFrame, "TOPRIGHT") + sectionFrame.minimizedLine:Height(1) end - sectionFrame:ClearAllPoints() - sectionFrame:Point("TOPLEFT", f.holderFrame, "TOPLEFT", 0, yOffset) - sectionFrame:Width(maxSectionWidth) - sectionFrame.occupied = {} - sectionFrame:Show() + if not section.minimized then + sectionFrame.minimizedLine:Hide() + else + sectionFrame.minimizedLine:Show() + end + sectionFrame.order = i + sectionFrame:Width(section.numColumns * (buttonSize + buttonSpacing) - buttonSpacing) + + local storedPositions = section.storedPositions + local processedSection = { + frame = sectionFrame, + buttons = {}, + db = section, + } + updateSortMethods(processedSection) + updateCollectionMethods(processedSection) - local sectionButtons = {} if section.isSpecialBag then - sectionButtons = specialButtons[section.bagID] + local bagID = section.bagID + local buttonsSpecial = specialButtons[bagID] + tsort(buttonsSpecial, function(a, b) + return (storedPositions[a.bagID..'-'..a.slotID] or 999) < (storedPositions[b.bagID..'-'..b.slotID] or 999) + end) + for _, button in ipairs(buttonsSpecial) do + if button.hasItem then + local itemID = B_GetItemID(nil, bagID, button.slotID) + itemCounts[itemID] = GetItemCount(itemID) + button.itemID = itemID + tinsert(processedSection.buttons, button) + section.storedPositions[bagID..'-'..button.slotID] = #processedSection.buttons + else + button.itemID = false + button:Hide() + end + buttonMap[bagID][button.slotID] = processedSection + end + elseif section.shouldPopulate then + local reserved = {} + for j, button in ipairs(buttons) do + local bagID, slotID = button.bagID, button.slotID + local hash = bagID..'-'..slotID + local _, pass = self:EvaluateItem({processedSection}, bagID, slotID, button.itemID or B_GetItemID(nil, bagID, slotID)) + if pass or i == #sections then + tinsert(reserved, {index = j, hash = hash}) + tinsert(processedSection.buttons, button) + buttonMap[bagID][slotID] = processedSection + section.storedPositions[hash] = #processedSection.buttons + elseif section.storedPositions[hash] then + section.storedPositions[hash] = nil + end + end + tsort(reserved, function(a,b) return a.index > b.index end) + for _, info in ipairs(reserved) do + tremove(buttons, info.index) + for _, otherSection in ipairs(sections) do + if otherSection ~= section then + local removedPos = otherSection.storedPositions[info.hash] + if removedPos then + otherSection.storedPositions[info.hash] = nil + for hash, pos in pairs(otherSection.storedPositions) do + if pos > removedPos then + otherSection.storedPositions[hash] = pos - 1 + end + end + end + end + end + end + section.shouldPopulate = nil else - for _ = 1, section.length do - local button = tremove(buttons, 1) - if not button then break end - tinsert(sectionButtons, button) + local reserved = {} + for j, button in ipairs(buttons) do + local bagID, slotID = button.bagID, button.slotID + local pos = storedPositions[bagID..'-'..slotID] + if pos then + tinsert(reserved, j) + tinsert(processedSection.buttons, button) + buttonMap[bagID][slotID] = processedSection + end + end + tsort(reserved, function(a,b) return a > b end) + for _, index in ipairs(reserved) do + tremove(buttons, index) end + tsort(processedSection.buttons, function(a, b) + return (storedPositions[a.bagID..'-'..a.slotID] or 999) < (storedPositions[b.bagID..'-'..b.slotID] or 999) + end) end - if #sectionButtons == 0 then break end + sectionFrame.title = sectionFrame.title or sectionFrame:CreateFontString(nil, "OVERLAY") + sectionFrame.title:SetFont(LSM:Fetch('font', section.title.font), section.title.size, section.title.flags) + sectionFrame.title:SetText(section.title.text) + sectionFrame.title:SetTextColor(unpack(section.title.color)) + sectionFrame.title:SetJustifyH(section.title.justify or "LEFT") + sectionFrame.title:Show() + sectionFrame.title:ClearAllPoints() - if section.title.enabled then - sectionFrame.title = sectionFrame.title or sectionFrame:CreateFontString(nil, "OVERLAY") - sectionFrame.title:SetFont(LSM:Fetch('font', section.title.font), section.title.size, section.title.flags) - sectionFrame.title:SetText(section.title.text) - sectionFrame.title:SetTextColor(unpack(section.title.color)) - sectionFrame.title:Show() - sectionFrame.title:ClearAllPoints() - end + sectionFrame.header:ClearAllPoints() + sectionFrame.header:Point("BOTTOMLEFT", sectionFrame, "TOPLEFT", 0, section.title.yOffset) + sectionFrame.header:Point("BOTTOMRIGHT", sectionFrame, "TOPRIGHT", 0, section.title.yOffset) + sectionFrame.header:Size(section.title.size) + + sectionFrame.minimizedLine:SetTexture(unpack(section.title.color)) if section.icon.enabled then sectionFrame.icon = sectionFrame.icon or sectionFrame:CreateTexture(nil, "OVERLAY") @@ -1353,83 +1940,133 @@ function mod:ConfigureContainer(f, db, maxSectionWidth, numContainerColumns, but sectionFrame.icon:Size(section.icon.size, section.icon.size) sectionFrame.icon:Show() sectionFrame.icon:ClearAllPoints() - elseif sectionFrame.icon then - sectionFrame.icon:Hide() - sectionFrame.icon = nil - end - - if section.title.enabled and section.icon.enabled then if section.icon.toText then sectionFrame.icon:Point(section.icon.point, sectionFrame.title, section.icon.relativeTo, section.icon.xOffset, section.icon.yOffset) - sectionFrame.title:Point(section.title.point, sectionButtons[1], section.title.relativeTo, section.title.xOffset, section.title.yOffset) + sectionFrame.title:Point("BOTTOMLEFT", sectionFrame, "TOPLEFT", section.title.xOffset, section.title.yOffset) + sectionFrame.title:Point("BOTTOMRIGHT", sectionFrame, "TOPRIGHT", 0, section.title.yOffset) elseif section.title.toIcon then sectionFrame.title:Point(section.title.point, sectionFrame.icon, section.title.relativeTo, section.title.xOffset, section.title.yOffset) - sectionFrame.icon:Point(section.icon.point, sectionButtons[1], section.icon.relativeTo, section.icon.xOffset, section.icon.yOffset) + sectionFrame.title:Point("BOTTOMRIGHT", sectionFrame, "TOPRIGHT", 0, section.title.yOffset) + sectionFrame.icon:Point("BOTTOMLEFT", sectionFrame, "TOPLEFT", section.icon.xOffset, section.icon.yOffset) end - elseif section.title.enabled then - sectionFrame.title:Point(section.title.point, sectionButtons[1], section.title.relativeTo, section.title.xOffset, section.title.yOffset) - elseif section.icon.enabled then - sectionFrame.icon:Point(section.icon.point, sectionButtons[1], section.icon.relativeTo, section.icon.xOffset, section.icon.yOffset) + minIconLeft = min(minIconLeft, section.icon.xOffset) + else + if sectionFrame.icon then + sectionFrame.icon:Hide() + sectionFrame.icon = nil + end + sectionFrame.title:Point("BOTTOMLEFT", sectionFrame, "TOPLEFT", section.title.xOffset, section.title.yOffset) + sectionFrame.title:Point("BOTTOMRIGHT", sectionFrame, "TOPRIGHT", -buttonSpacing, section.title.yOffset) end - for i, button in ipairs(sectionButtons) do - sectionFrame.occupied[i] = B_GetItemID(nil, button.bagID, button.slotID) - end + tinsert(processedSections, processedSection) + end - local processedSection = { - frame = sectionFrame, - buttons = sectionButtons, - numColumns = numContainerColumns, - sectionSpacing = db.sectionSpacing, - db = section, - order = i, - } + for _, button in ipairs(buttons) do + local bagID, slotID = button.bagID, button.slotID + local targetSection = self:EvaluateItem(processedSections, bagID, slotID, button.itemID or B_GetItemID(nil, bagID, slotID)) + tinsert(targetSection.buttons, button) + buttonMap[bagID][slotID] = targetSection + targetSection.db.storedPositions[bagID..'-'..slotID] = #targetSection.buttons + end - self:HandleControls(f, processedSection, buttonSize) - tinsert(processedSections, processedSection) + while #sections < #layoutSections do + local section = layoutSections[#layoutSections] + for _, button in ipairs(section.buttons) do + if button.highlight then + button.highlight:Hide() + button.highlight = nil + end + end + local frame = section.frame + if frame then + frame:Hide() + section.frame = nil + end + tremove(layoutSections, #layoutSections) end f.currentLayout = { sections = processedSections, - buttonSize = buttonSize + numColumns = numColumns, + maxButtons = maxButtons, + buttonSize = buttonSize, + buttonSpacing = buttonSpacing, + filter = activeFilters, } -end -function mod:Layout(self, isBank) - if not E.private.bags.enable then return end - local f = B_GetContainerFrame(nil, isBank) - if not f then return end - - local db = E.db.Extras.general[modName] - if db.SplitStack.enabled or db.EasierProcessing.enabled then - for _, bagID in ipairs(f.BagIDs) do - if f.Bags[bagID] then - for slotID = 1, f.Bags[bagID].numSlots do - local button = f.Bags[bagID][slotID] - if button then - for _, info in pairs(mod.localhooks) do - for type in pairs(info) do - if not mod:IsHooked(button, type) then - mod:SecureHookScript(button, type, function(self, ...) runAllScripts(self, type, ...) end) + for i = -1, NUM_BANKBAGSLOTS do + local holder = f.ContainerHolder[i] + if holder and i ~= 0 then + for script, val in pairs({["OnDragStart"] = true, ["OnDragStop"] = false}) do + if not self:IsHooked(holder, script) then + self:SecureHookScript(holder, script, function() + removingBag = val and i - 1 + end) + end + end + if not self:IsHooked(holder, "OnEnter") then + self:SecureHookScript(holder, "OnEnter", function(self) + holderTT:SetTemplate() + holderTT:SetOwner(holder, "ANCHOR_RIGHT") + holderTT:AddLine(L["Alt-Click: free bag slots, if possible."]) + holderTT:Show() + end) + end + if not self:IsHooked(holder, "OnLeave") then + self:SecureHookScript(holder, "OnLeave", function(self) + holderTT:Hide() + end) + end + if not self:IsHooked(holder, "OnMouseDown") then + self:SecureHookScript(holder, "OnMouseDown", function(self) + if IsAltKeyDown() then + if InCombatLockdown() then + print(core.customColorBad..ERR_NOT_IN_COMBAT) + return + end + local bagID = self.id + local bag = f.Bags[bagID] + if bag and bag.numSlots > 0 then + local heldButtons, emptyButtons = {}, {} + for slotID = 1, GetContainerNumSlots(bagID) do + local button = bag[slotID] + if button and button.hasItem then + tinsert(heldButtons, button) + end + end + for button in pairs(buttonMap[f]) do + if button.bagID ~= bagID then + tinsert(emptyButtons, button) end end + if #heldButtons > 0 and #emptyButtons > 0 then + self.elapsed = 0 + self:SetScript("OnUpdate", function(self, elapsed) + self.elapsed = self.elapsed + elapsed + if self.elapsed > 0.1 then + local held = tremove(heldButtons) + local empty = tremove(emptyButtons) + B_PickupItem(nil, held.bagID, held.slotID) + B_PickupItem(nil, empty.bagID, empty.slotID) + if #heldButtons == 0 or #emptyButtons == 0 then + self:SetScript("OnUpdate", nil) + end + end + end) + end end end - end + end) + end + if not self:IsHooked(holder, "OnHide") then + self:SecureHookScript(holder, "OnHide", function(self) + self:SetScript("OnUpdate", nil) + end) end end end - if not db.BagsExtended.enabled then return end - - local buttonSpacing = E.Border * 2 - local buttonSize = isBank and B.db.bankSize or B.db.bagSize - local containerWidth = (isBank and B.db.bankWidth) or B.db.bagWidth - local numContainerColumns = floor(containerWidth / (buttonSize + buttonSpacing)) - local maxSectionWidth = (numContainerColumns * (buttonSize + buttonSpacing) - buttonSpacing) + buttonSize - - f:Width(maxSectionWidth) - if not isBank then if not f.heldCurrencies then f.heldCurrencies = CreateFrame("Button", nil, f, "UIPanelButtonTemplate") @@ -1446,8 +2083,10 @@ function mod:Layout(self, isBank) for i = 1, numCurrencies do local _, isHeader, _, _, _, count, _, icon, itemID = GetCurrencyListInfo(i) if not isHeader and count > 0 then - if itemID == 43307 then icon = "Interface\\PVPFrame\\PVP-ArenaPoints-Icon" - elseif itemID == 43308 then icon = "Interface\\PVPFrame\\PVP-Currency-"..UnitFactionGroup("player") + if itemID == 43307 then + icon = "Interface\\PVPFrame\\PVP-ArenaPoints-Icon" + elseif itemID == 43308 then + icon = "Interface\\PVPFrame\\PVP-Currency-"..UnitFactionGroup("player") end hasCurrencies = true local name, _, quality = GetItemInfo(itemID) @@ -1496,453 +2135,660 @@ function mod:Layout(self, isBank) end end - mod:ConfigureContainer(f, db.BagsExtended.containers[isBank and 'bank' or 'bags'], maxSectionWidth, numContainerColumns, buttonSize) + if not f.emptyButton then + f.emptyButton = CreateFrame("Button", '$parentEmptyButton', f, "UIPanelButtonTemplate") + f.emptyButton:Size(24) + f.emptyButton:Point("BOTTOMLEFT", f.holderFrame, "TOPLEFT", 0, 6) + f.emptyButton.showEmptySections = false + f.emptyButton.hideHints = db.hideHints + f.emptyButton:EnableMouseWheel(true) + + f.emptyButton.eyeTex = f.emptyButton:CreateTexture(nil, "OVERLAY") + f.emptyButton.eyeTex:Point("BOTTOMRIGHT", f.emptyButton, "BOTTOMRIGHT") + f.emptyButton.eyeTex:SetTexture("Interface\\LFGFrame\\LFG-Eye") + f.emptyButton.eyeTex:Size(16) + f.emptyButton.eyeTex:SetTexCoord(0, 0.1, 0, 0.20) + f.emptyButton.eyeTex:Hide() + + f.emptyButton.highlight = CreateFrame("Frame", nil, f.emptyButton) + f.emptyButton.highlight:SetFrameLevel(999) + f.emptyButton.highlight:Point("CENTER", f.emptyButton, "CENTER") + f.emptyButton.highlight:Size(30) + f.emptyButton.highlight:Hide() + + f.emptyButton.highlight.tex = f.emptyButton.highlight:CreateTexture(nil, "OVERLAY") + f.emptyButton.highlight.tex:Point("TOPLEFT", f.emptyButton.highlight, "TOPLEFT") + f.emptyButton.highlight.tex:Point("BOTTOMRIGHT", f.emptyButton.highlight, "BOTTOMRIGHT") + f.emptyButton.highlight.tex:SetBlendMode("ADD") + + f.emptyButton.normalTex = f.emptyButton:CreateTexture(nil, "ARTWORK") + f.emptyButton.normalTex:SetTexture("Interface\\Minimap\\Tracking\\Banker") + f.emptyButton.normalTex:Point("CENTER") + f.emptyButton.normalTex:Size(24) + + f.emptyButton.pushedTex = f.emptyButton:CreateTexture(nil, "ARTWORK") + f.emptyButton.pushedTex:SetTexture("Interface\\Minimap\\Tracking\\Banker") + f.emptyButton.pushedTex:Point("CENTER") + f.emptyButton.pushedTex:Size(24) + + f.emptyButton.highlightTex = f.emptyButton:CreateTexture(nil, "ARTWORK") + f.emptyButton.highlightTex:SetTexture("Interface\\Minimap\\Tracking\\Banker") + f.emptyButton.highlightTex:Point("CENTER") + f.emptyButton.highlightTex:SetAlpha(0.25) + f.emptyButton.highlightTex:Size(24) + + f.emptyButton:SetNormalTexture(f.emptyButton.normalTex) + f.emptyButton:SetPushedTexture(f.emptyButton.pushedTex) + f.emptyButton:SetHighlightTexture(f.emptyButton.highlightTex) + + f.emptyButton.emptySlotsText = f.emptyButton:CreateFontString(nil, "OVERLAY") + f.emptyButton.emptySlotsText:Point("BOTTOMLEFT", f.emptyButton.totalEmptySlotsText, "BOTTOMLEFT") + f.emptyButton.emptySlotsText:FontTemplate() + local empty = 0 + for _ in pairs(buttonMap[f]) do + empty = empty + 1 + end + f.emptyButton.emptySlotsText:SetText(empty) - if incombat then - for _, section in ipairs(f.currentLayout.sections) do - local sectionFrame = section.frame - local button = section.buttons[#section.buttons] - sectionFrame.concatenateButton:ClearAllPoints() - sectionFrame.concatenateButton:Point("TOPLEFT", button, "TOPRIGHT", buttonSpacing, 0) - sectionFrame.expandButton:ClearAllPoints() - sectionFrame.expandButton:Point("BOTTOMLEFT", button, "BOTTOMRIGHT", buttonSpacing, 0) - mod:UpdateEmptySlotCount(button, 0) - end - mod:RegisterEvent("PLAYER_REGEN_ENABLED", function() - for _, section in ipairs(f.currentLayout.sections) do - for _, button in ipairs(section.buttons) do - RegisterStateDriver(button, "visibility", "[combat] show") - end + f.emptyButton.emptySlotsSelection = 0 + f.emptyButton:SetScript("OnMouseWheel", function(self) + updateEmptyButtonCount(f) + self:GetScript("OnEnter")(self) + end) + f.emptyButton:SetScript("OnReceiveDrag", function(self) + if f.draggedButton then + f.draggedButton.atHeader = 'evaluate' + ClearCursor() + f.draggedButton = nil end - incombat = false - updateLayouts() - mod:RegisterEvent("PLAYER_REGEN_ENABLED", function() incombat = false updateLayouts() end) end) - end - - local minIconLeft = huge - for _, section in ipairs(f.currentLayout.sections) do - local prevButton - for i, button in ipairs(section.buttons) do - buttonMap[button.bagID][button.slotID] = section + f.emptyButton:SetScript("OnEnter", function(self) + local cursorInfo = GetCursorInfo() + if cursorInfo == 'item' or cursorInfo == 'merchant' then + local _, itemID, itemLink + if cursorInfo == 'item' then + _, _, itemLink = GetCursorInfo() + else + _, itemID = GetCursorInfo() + itemLink = GetMerchantItemLink(itemID) + end - if not incombat then - RegisterStateDriver(button, "visibility", "[combat] show") + if itemLink then + local emptyButton + if removingBag then + for button in pairs(buttonMap[f]) do + if button.bagID ~= removingBag then + emptyButton = button + break + end + end + elseif self.emptySlotsSelection ~= 0 then + emptyButton = mod:FindEmpty(nil, f, self.emptySlotsSelection) + else + emptyButton = next(buttonMap[f]) + end + if emptyButton then + self.highlight.tex:SetTexture("Interface\\Buttons\\UI-Common-MouseHilight") + self.highlight.tex:SetVertexColor(0, 1, 0) + self.highlight:SetFrameLevel(f.emptyButton:GetFrameLevel()) + + emptyButton.atHeader = 'evaluate' + emptyButton:SetAllPoints(self) + emptyButton:SetAlpha(0) + emptyButton:Show() + elseif f.draggedButton then + self.highlight.shouldFade = true + self.highlight.tex:SetTexture("Interface\\Buttons\\UI-Common-MouseHilight") + self.highlight.tex:SetVertexColor(0, 1, 0) + E:UIFrameFadeIn(self.highlight, 0.2, self.highlight:GetAlpha(), 1) + else + self.highlight.shouldFade = true + self.highlight.tex:SetTexture("Interface\\Buttons\\UI-GROUPLOOT-PASS-HIGHLIGHT") + self.highlight.tex:SetVertexColor(1, 0, 0) + E:UIFrameFadeIn(self.highlight, 0.2, self.highlight:GetAlpha(), 1) + end + end end - - local col = (i - 1) % section.numColumns - local row = floor((i - 1) / section.numColumns) - - if not button.highlight then - button.highlight = CreateFrame("Frame", nil, button) - button.highlight:SetAllPoints() - - button.highlight.glow = CreateFrame("Frame", nil, button.highlight) - button.highlight.glow:SetAllPoints() - button.highlight.glow.tex = button.highlight.glow:CreateTexture(nil, "OVERLAY") - button.highlight.glow.tex:SetAllPoints() - button.highlight.glow.tex:SetTexture("Interface\\Buttons\\ButtonHilight-Square") - button.highlight.glow.tex:SetBlendMode("ADD") - - button.highlight.pulse = CreateFrame("Frame", nil, button.highlight) - button.highlight.pulse:SetAllPoints() - button.highlight.pulse.tex = button.highlight.pulse:CreateTexture(nil, "OVERLAY") - button.highlight.pulse.tex:SetAllPoints() - button.highlight.pulse.tex:SetTexture("Interface\\Cooldown\\star4") - button.highlight.pulse.tex:SetBlendMode("ADD") - - button.highlight:Hide() - - button.highlight:HookScript("OnShow", function(self) - E_Flash(nil, self.pulse, 1, true) - end) - - button.highlight:HookScript("OnHide", function(self) - E_StopFlash(nil, self.pulse) - end) + showEmptyButtonTT(f) + end) + f.emptyButton.highlight:SetScript("OnLeave", function(self) + if self.shouldFade then + self.shouldFade = false + E:UIFrameFadeOut(self.highlight, 0.2, self.highlight:GetAlpha(), 0) end - - if not mod:IsHooked(button, "OnEnter") then - mod:SecureHookScript(button, "OnEnter", function(self) - self.highlight:Hide() - end) + end) + f.emptyButton:SetScript("OnLeave", function(self) + if self.highlight.shouldFade then + self.highlight.shouldFade = false + E:UIFrameFadeOut(self.highlight, 0.2, self.highlight:GetAlpha(), 0) end - - button:ClearAllPoints() - if col == 0 then - if row == 0 then - button:Point("TOPLEFT", section.frame, "TOPLEFT", buttonSpacing, -(section.sectionSpacing or 0)/2 - buttonSpacing*2) + GameTooltip_Hide() + end) + f.emptyButton:SetScript("OnMouseUp", function(self) + self:ClearAllPoints() + self:Point("BOTTOMLEFT", f.holderFrame, "TOPLEFT", 0, 6) + end) + f.emptyButton:SetScript("OnMouseDown", function(self) + self:ClearAllPoints() + self:Point("BOTTOMLEFT", f.holderFrame, "TOPLEFT", 1, 5) + local draggingItem = GetCursorInfo() + if f.draggedButton then + f.draggedButton.atHeader = 'evaluate' + ClearCursor() + f.draggedButton = nil + end + local layout = f.currentLayout + if IsAltKeyDown() then + if IsShiftKeyDown() then + f.emptyButton.hideHints = not f.emptyButton.hideHints + db.hideHints = f.emptyButton.hideHints + showEmptyButtonTT(f) + elseif not draggingItem then + for _, section in ipairs(layout.sections) do + section.db.storedPositions = {} + end + mod:Layout(B, f.isBank) + end + elseif not draggingItem then + self.showEmptySections = not self.showEmptySections + self.showSizing = not self.showSizing + toggleLayoutMode(f, self.showSizing) + if self.showEmptySections then + f.emptyButton.eyeTex:Show() + for i, section in ipairs(layout.sections) do + f.forceShow = true + db.forceShow = true + mod:UpdateSection(f, #section.buttons, section, + layout.numColumns, layout.buttonSize, layout.buttonSpacing, i == #layout.sections) + end else - button:Point("TOP", section.buttons[i - section.numColumns], "BOTTOM", 0, -buttonSpacing) + f.emptyButton.eyeTex:Hide() + for i, section in ipairs(layout.sections) do + f.forceShow = false + db.forceShow = false + mod:UpdateSection(f, #section.buttons, section, + layout.numColumns, layout.buttonSize, layout.buttonSpacing, i == #layout.sections) + end end - else - button:Point("LEFT", prevButton, "RIGHT", buttonSpacing, 0) + E:StopFlash(self.highlight) + E:UIFrameFadeOut(self.highlight, 1, self.highlight:GetAlpha(), 0) end - - prevButton = button - end - mod:ToggleMinimizeSection(f, section, buttonSize) - if section.db.icon.enabled then - minIconLeft = min(minIconLeft, section.frame.icon:GetLeft()) - end - updateSortMethods(section) - updateCollectionMethods(section) - end - - if minIconLeft < f.holderFrame:GetLeft() then - local offset = f.holderFrame:GetLeft() - minIconLeft - local point, parent, relativeTo, _, y = f.holderFrame:GetPoint() - f.holderFrame:Point(point, parent, relativeTo, offset/2 - buttonSize/4, y) - f:Width(maxSectionWidth + offset) - else - f.holderFrame:ClearAllPoints() - f.holderFrame:Point("TOP", f, "TOP", -buttonSize/4, -f.topOffset) - f.holderFrame:Point("BOTTOM", f, "BOTTOM", 0, 8) + end) end - mod:ScanBags(f, true) -end - -function mod:ResizeFrame(f, buttonSize) - local yOffset = -buttonSize/4 - local totalHeight = f.topOffset + f.bottomOffset - local layout = f.currentLayout + if not f.qualityFilterBar then + f.qualityFilterBar = CreateFrame("Frame", '$parentQualityFilterBar', f) + f.qualityFilterBar:Point("BOTTOMLEFT", f.holderFrame, "BOTTOMLEFT") + f.qualityFilterBar:Point("BOTTOMRIGHT", f.holderFrame, "BOTTOMRIGHT") + f.qualityFilterBar:Height(5) - for i, section in ipairs(layout.sections) do - local sectionFrame = section.frame - local sectionHeight = 0 - if not incombat then - sectionFrame:ClearAllPoints() - sectionFrame:Point("TOPLEFT", f.holderFrame, "TOPLEFT", 0, yOffset) - sectionHeight = sectionFrame:GetHeight() - else - sectionHeight = sectionFrame.height + if not isBank then + f.currencyButton:ClearAllPoints() + f.currencyButton:Point("TOPLEFT", f.qualityFilterBar, "BOTTOMLEFT", 0, db.qualityFilterShown and 28 or 18) + f.currencyButton:Point("TOPRIGHT", f.qualityFilterBar, "BOTTOMRIGHT", 0, db.qualityFilterShown and 28 or 18) end - yOffset = yOffset - sectionHeight - if i == #layout.sections then - totalHeight = totalHeight + buttonSize/2 - else - yOffset = yOffset - section.sectionSpacing - totalHeight = totalHeight + section.sectionSpacing - end - totalHeight = totalHeight + sectionHeight - end - - f:Height(totalHeight) -end + local barWidth = (((buttonSize + buttonSpacing) * numColumns) - buttonSpacing - 30)/7 + for i = 6, 0, -1 do + local color = ITEM_QUALITY_COLORS[i] + local bar = CreateFrame("Button", nil, f.qualityFilterBar) + bar:Size(barWidth, 5) + bar:Point("TOPLEFT", f.qualityFilterBar, "TOPLEFT", i * (barWidth+5), 0) + bar:CreateBackdrop() + bar:StyleButton() + bar:RegisterForClicks("LeftButtonDown", "RightButtonDown") + bar.isActive = true + bar.quality = i + + if not db.qualityFilterShown then + bar:Hide() + end -function mod:ScanBags(f, updateLast) - local changes, inventory = {}, {} - for _, bagID in ipairs(f.BagIDs) do - local bag = f.Bags[bagID] - if bag and bag.numSlots > 0 then - changes[bagID] = {} - for slotID = 1, bag.numSlots do - local button = bag[slotID] - local itemID = B_GetItemID(nil, bagID, slotID) - if button and itemID then - if not inventory[itemID] then - local _, _, _, _, _, _, _, maxStack = GetItemInfo(itemID) - inventory[itemID] = { positions = {}, count = 0, maxStack = maxStack or 1 } - end - tinsert(inventory[itemID].positions, {bagID = bagID, slotID = slotID}) - inventory[itemID].count = inventory[itemID].count + button.count/inventory[itemID].maxStack - if not tooltipInfo[itemID] then - tooltipInfo[itemID] = lower(gsub(gsub(getItemTooltipText(bagID, slotID), '%s+', ''), '%p+', '')) + bar.bg = bar:CreateTexture(nil, "ARTWORK") + bar.bg:SetAllPoints(bar) + bar.bg:SetTexture(color.r, color.g, color.b) + + bar:SetScript("OnClick", function(self, clickButton) + if clickButton == "RightButton" then + for j = 0, 6 do + local filterBar = f.qualityFilterBar[j+1] + if filterBar then + local filterColor = ITEM_QUALITY_COLORS[j] + if filterBar == self then + filterBar.bg:SetTexture(filterColor.r, filterColor.g, filterColor.b) + filterBar.isActive = true + activeFilters[j] = true + else + filterBar.bg:SetTexture(filterColor.r * 0.5, filterColor.g * 0.5, filterColor.b * 0.5) + filterBar.isActive = false + activeFilters[j] = false + end + end end - end - end - end - end - - if not updateLast then - for itemID, info in pairs(inventory) do - local lastInfo = lastScan[f][itemID] - if not lastInfo then - for _, pos in ipairs(info.positions) do - changes[pos.bagID][pos.slotID] = itemID - end - elseif info.count > lastInfo.count then - for _, pos in ipairs(info.positions) do - local isNewPosition = true - for _, lastPos in ipairs(lastInfo.positions) do - if pos.bagID == lastPos.bagID and pos.slotID == lastPos.slotID then - isNewPosition = false - break + for j, section in ipairs(f.currentLayout.sections) do + for _, button in ipairs(section.buttons) do + local rarity = button.rarity or select(3,GetItemInfo(button.itemID or B_GetItemID(nil, button.bagID, button.slotID))) + button.isHidden = (rarity ~= i) + if button.isHidden then + button:Hide() + else + button:Show() + end + end + mod:UpdateSection(f, 1, section, numColumns, buttonSize, buttonSpacing, j == #f.currentLayout.sections) + end + elseif self.isActive then + self.bg:SetTexture(color.r * 0.5, color.g * 0.5, color.b * 0.5) + self.isActive = false + activeFilters[i] = false + for j, section in ipairs(f.currentLayout.sections) do + for _, button in ipairs(section.buttons) do + local rarity = button.rarity or select(3,GetItemInfo(button.itemID or B_GetItemID(nil, button.bagID, button.slotID))) + if rarity == i then + button.isHidden = true + button:Hide() + end end + mod:UpdateSection(f, 1, section, numColumns, buttonSize, buttonSpacing, j == #f.currentLayout.sections) end - if isNewPosition then - changes[pos.bagID][pos.slotID] = itemID + else + self.bg:SetTexture(color.r, color.g, color.b) + self.isActive = true + activeFilters[i] = true + for j, section in ipairs(f.currentLayout.sections) do + for _, button in ipairs(section.buttons) do + local rarity = button.rarity or select(3,GetItemInfo(button.itemID or B_GetItemID(nil, button.bagID, button.slotID))) + if rarity == i then + button.isHidden = false + button:Show() + end + end + mod:UpdateSection(f, 1, section, numColumns, buttonSize, buttonSpacing, j == #f.currentLayout.sections) end end + end) + f.qualityFilterBar[i+1] = bar + activeFilters[i] = true + end + f.qualityFilterButton = CreateFrame("Button", '$parentQualityFilterButton', f.holderFrame) + f.qualityFilterButton:Size(16 + E.Border) + f.qualityFilterButton:SetTemplate() + f.qualityFilterButton:Point("RIGHT", isBank and f.purchaseBagButton or f.vendorGraysButton, "LEFT", -5, 0) + f.qualityFilterButton:SetNormalTexture("Interface\\Icons\\INV_Misc_Gear_01") + f.qualityFilterButton:GetNormalTexture():SetTexCoord(unpack(E.TexCoords)) + f.qualityFilterButton:GetNormalTexture():SetInside() + f.qualityFilterButton:SetPushedTexture("Interface\\Icons\\INV_Misc_Gear_01") + f.qualityFilterButton:GetPushedTexture():SetTexCoord(unpack(E.TexCoords)) + f.qualityFilterButton:GetPushedTexture():SetInside() + f.qualityFilterButton:StyleButton(nil, true) + f.qualityFilterButton.ttText = FILTERS + f.qualityFilterButton:SetScript("OnEnter", B.Tooltip_Show) + f.qualityFilterButton:SetScript("OnLeave", GameTooltip_Hide) + f.qualityFilterButton:SetScript("OnClick", function(self) + if db.qualityFilterShown then + for _, bar in ipairs(f.qualityFilterBar) do + bar:Hide() + end + f.currencyButton:ClearAllPoints() + f.currencyButton:Point("TOPLEFT", f.qualityFilterBar, "BOTTOMLEFT", 0, 18) + f.currencyButton:Point("TOPRIGHT", f.qualityFilterBar, "BOTTOMRIGHT", 0, 18) + f.bottomOffset = f.bottomOffset - 10 + else + for _, bar in ipairs(f.qualityFilterBar) do + bar:Show() + end + f.currencyButton:ClearAllPoints() + f.currencyButton:Point("TOPLEFT", f.qualityFilterBar, "BOTTOMLEFT", 0, 28) + f.currencyButton:Point("TOPRIGHT", f.qualityFilterBar, "BOTTOMRIGHT", 0, 28) + f.bottomOffset = f.bottomOffset + 10 end + local section = f.currentLayout.sections[#f.currentLayout.sections] + mod:UpdateSection(f, #section.buttons, section, numColumns, buttonSize, buttonSpacing, true) + db.qualityFilterShown = not db.qualityFilterShown + end) + end + + f.editBox:ClearAllPoints() + if (isBank and B.db.bankWidth or B.db.bagWidth) < 250 then + if not isBank then + f.editBox:Point("BOTTOMLEFT", f.holderFrame, "TOPLEFT", E.Border * 2 + 18, E.Border * 2 - 32) + f.editBox:Point("TOPRIGHT", f.sortButton, "BOTTOMRIGHT", 0, -E.Border * 2 - 2) + f.sortButton:ClearAllPoints() + f.sortButton:Point("TOPRIGHT", f.goldText, "BOTTOMRIGHT", 0, -E.Border * 2) + else + f.editBox:Point("BOTTOMLEFT", f.holderFrame, "TOPLEFT", E.Border * 2 + 18, E.Border * 2 - 32) + f.editBox:Point("TOPRIGHT", f.sortButton, "BOTTOMRIGHT", 0, -E.Border * 2 - 2) + f.sortButton:ClearAllPoints() + f.sortButton:Point("TOPRIGHT", f.bagText, "BOTTOMRIGHT", 0, -E.Border * 2) + end + else + f.editBox:Point("BOTTOMLEFT", f.holderFrame, "TOPLEFT", E.Border * 2 + 48, E.Border * 2 + 2 + E.Border) + f.editBox:Point("TOPRIGHT", f.qualityFilterButton, "TOPLEFT", -5, -2) + if not isBank then + f.sortButton:ClearAllPoints() + f.sortButton:Point("RIGHT", f.goldText, "LEFT", -5, E.Border * 2) + else + f.sortButton:ClearAllPoints() + f.sortButton:Point("RIGHT", f.bagText, "LEFT", -5, E.Border * 2) end end - lastScan[f] = inventory + local offset1, offset2 = 8 + if minIconLeft < 0 then + offset2 = offset1 - minIconLeft + end + + f.holderFrame:ClearAllPoints() + f.holderFrame:Point("TOPLEFT", f, "TOPLEFT", offset2 or offset1, -f.topOffset+(buttonSize/4)) + f.holderFrame:Point("BOTTOMRIGHT", f, "BOTTOMRIGHT", -offset1, 8) + + f:Width(numColumns * (buttonSize + buttonSpacing) + (offset2 or offset1) * 2 - buttonSpacing) - return changes + for _, section in ipairs(f.currentLayout.sections) do + self:UpdateSection(f, 1, section, numColumns, buttonSize, buttonSpacing) + end end -function mod:ApplyBagChanges(f, changes) - local updatedSections = {} - local occupied = {} - local layout = f.currentLayout - for bagID, slots in pairs(changes) do - for slotID, itemID in pairs(slots) do - local targetBagID, targetSlotID, section = mod:EvaluateItem(layout.sections, bagID, slotID, itemID) - if targetBagID and targetSlotID then - if occupied[targetBagID..'-'..targetSlotID] then - for _, button in ipairs(section.buttons) do - local bagID, slotID = button.bagID, button.slotID - if not occupied[bagID..'-'..slotID] and not button.hasItem then - targetBagID, targetSlotID = bagID, slotID - break +function mod:Layout(self, isBank) + if not E.private.bags.enable then return end + local f = B_GetContainerFrame(nil, isBank) + if not f then return end + + if not f.SplitStackHandler then + f.SplitStackHandler = CreateFrame("Frame", nil, f) + f.SplitStackHandler:SetScript("OnHide", function(self) + self.isStacking = false + self:SetScript("OnUpdate", nil) + end) + end + for _, bagID in ipairs(f.BagIDs) do + local bag = f.Bags[bagID] + if bag then + for slotID = 1, bag.numSlots do + local button = bag[slotID] + if button then + for _, info in pairs(mod.localhooks) do + for event in pairs(info) do + if not mod:IsHooked(button, event) then + mod:SecureHookScript(button, event, function(self, ...) runAllScripts(self, event, ...) end) + end end end end - local currentSection = buttonMap[bagID][slotID] - local targetSection = buttonMap[targetBagID][targetSlotID] - if currentSection ~= targetSection then - B_PickupItem(nil, bagID, slotID) - B_PickupItem(nil, targetBagID, targetSlotID) - mod:UpdateSection(f, section, layout.buttonSize) - occupied[targetBagID..'-'..targetSlotID] = true - updatedSections[section] = true - end - end - end - end - return updatedSections -end + end + end + end -function mod:UpdateBagSlots(self, f, bagID) - local layout = f.currentLayout - if not layout then return end + if not E.db.Extras.general[modName].BagsExtendedV2.enabled then return end + local db = E.db.Extras.general[modName].BagsExtendedV2.containers[isBank and 'bank' or 'bags'] - if not equippedBags[bagID] then equippedBags[bagID] = GetBagName(bagID) end + local buttonSpacing = db.buttonSpacing or E.Border * 2 + local buttonSize = isBank and B.db.bankSize or B.db.bagSize + local numColumns = floor((isBank and B.db.bankWidth or B.db.bagWidth) / (buttonSize + buttonSpacing)) - for _, section in ipairs(layout.sections) do - mod:UpdateSection(f, section, layout.buttonSize) + if db.qualityFilterShown then + f.newbottomOffset = (db.bottomOffset or 0) + 10 + else + f.newbottomOffset = db.bottomOffset or 0 + end + if (isBank and B.db.bankWidth or B.db.bagWidth) < 250 then + f.newtopOffset = (db.topOffset or 0) + 42 + else + f.newtopOffset = db.topOffset or 0 end - if updatePending then return end - updatePending = true - - E_Delay(nil, 0.1, function() - if not incombat then - mod:ApplyBagChanges(f, mod:ScanBags(f)) - for bagID, bagName in pairs(equippedBags) do - if bagName ~= GetBagName(bagID) then - -- due to increased load (i guess?) introduced by this plugin, real bag removal isn't being registered properly - equippedBags[bagID] = GetBagName(bagID) - B:UpdateAll() - end - end - updatePending = false - end - end) + updateSetsInfo() + mod:ConfigureContainer(f, isBank, db, numColumns, buttonSize, buttonSpacing) end function mod:UpdateSlot(self, f, bagID, slotID) - if not f.currentLayout - or (f.Bags[bagID] and f.Bags[bagID].numSlots ~= GetContainerNumSlots(bagID)) - or not f.Bags[bagID] or not f.Bags[bagID][slotID] then return end - - local button = f.Bags[bagID][slotID] - if not incombat and button.isHidden then button:Hide() end -end + local bag = f.Bags[bagID] + local bagMap = buttonMap[bagID] + if not bag or not bag[slotID] or not bagMap or (bag.numSlots ~= GetContainerNumSlots(bagID)) then return end -function mod:UpdateSection(f, section, buttonSize, combatUpd) - local sectionFrame = section.frame - local buttons = section.buttons + local layout = f.currentLayout + local button = bag[slotID] + local bagType = bag.type - if incombat and not combatUpd then - if f:IsShown() then - sectionFrame.newUnshown = sectionFrame.newUnshown or {} - for i in ipairs(buttons) do - sectionFrame.newUnshown[i] = true + if not button.hasItem then + button:Hide() + local itemID = button.itemID + if itemID then + itemCounts[itemID] = GetItemCount(itemID) + button.itemID = false + local targetSection = bagMap[slotID] + if targetSection then + local buttonPos = targetSection.db.storedPositions[bagID..'-'..slotID] or 1 + targetSection.db.storedPositions[bagID..'-'..slotID] = nil + tremove(targetSection.buttons, buttonPos) + if not bagType or bagType == 0 then + buttonMap[f][button] = true + bagMap[slotID] = nil + end + local buttons = targetSection.buttons + local buttonsLen = #buttons + for i = buttonPos, buttonsLen do + local button = buttons[i] + if button then + targetSection.db.storedPositions[button.bagID..'-'..button.slotID] = i + end + end + mod:UpdateSection(f, min(buttonsLen, buttonPos), targetSection, layout.numColumns, layout.buttonSize, layout.buttonSpacing) + updateEmptyButtonCount(f, true) end end - return - end - - local buttonSpacing = E.Border * 2 - local sectionHeaderHeight = section.sectionSpacing or 0 - local visibleButtons, lastEmpty = 0, 0 - local oldNumRows = section.numRows or 0 - - if sectionFrame.minimized and not incombat then - sectionFrame:Height(section.sectionSpacing) - buttons[1]:Point("TOPLEFT", sectionFrame, "TOPLEFT", buttonSpacing, -sectionHeaderHeight/2 - buttonSpacing*2) - if sectionFrame.title then - local minimizedCount = sectionFrame.minimizedCount or 0 - sectionFrame.newUnshown = sectionFrame.newUnshown or {} - for i, button in ipairs(buttons) do - local occupied, unshown = sectionFrame.occupied[i], sectionFrame.newUnshown[i] - local itemID = B_GetItemID(nil, button.bagID, button.slotID) - if not occupied or (itemID and occupied ~= itemID) then - sectionFrame.occupied[i] = itemID - if not unshown and itemID then - minimizedCount = minimizedCount + 1 - sectionFrame.newUnshown[i] = true - button.highlight:Show() - elseif unshown and not itemID then - minimizedCount = minimizedCount - 1 - sectionFrame.newUnshown[i] = false + else + local oldID = button.itemID + local itemID = B_GetItemID(nil, bagID, slotID) + local itemCount = GetItemCount(itemID) + if button.isHidden then + button:Hide() + elseif not oldID then + local targetSection + buttonMap[f][button] = nil + if itemCounts[itemID] ~= itemCount then + if not button:IsVisible() then + button.highlight:Show() + end + end + if button.atHeader then + if button.atHeader == 'evaluate' then + targetSection = (bagType and bagType ~= 0) and bagMap[slotID] or mod:EvaluateItem(layout.sections, bagID, slotID, itemID) + f.emptyButton.highlight:SetFrameLevel(999) + E:UIFrameFadeOut(f.emptyButton.highlight, 0.2, f.emptyButton.highlight:GetAlpha(), 0) + else + local header = button.atHeader.frame.header + targetSection = button.atHeader + header:SetFrameLevel(999) + E:UIFrameFadeOut(header.highlight, 0.2, header.highlight:GetAlpha(), 0) + if header.prevEmptySlotsSelection then + f.emptyButton.emptySlotsSelection = header.prevEmptySlotsSelection + header.prevEmptySlotsSelection = nil + end + end + button:SetAlpha(1) + button.atHeader = false + else + targetSection = mod:EvaluateItem(layout.sections, bagID, slotID, itemID) + end + if targetSection then + local buttons = targetSection.buttons + tinsert(buttons, button) + bagMap[slotID] = targetSection + targetSection.db.storedPositions[bagID..'-'..slotID] = #buttons + local rarity = button.rarity or select(3,GetItemInfo(itemID)) + if not layout.filter[rarity] then + button.isHidden = true + button:Hide() + else + mod:UpdateSection(f, #buttons, targetSection, layout.numColumns, layout.buttonSize, layout.buttonSpacing) + end + end + updateEmptyButtonCount(f, true) + elseif button.shouldEvaluate then + local currentSection = bagMap[slotID] + local targetSection = mod:EvaluateItem(layout.sections, bagID, slotID, itemID) + if currentSection then + local buttonPos = currentSection.db.storedPositions[bagID..'-'..slotID] or 1 + currentSection.db.storedPositions[bagID..'-'..slotID] = nil + tremove(currentSection.buttons, buttonPos) + local buttons = currentSection.buttons + local buttonsLen = #buttons + for i = buttonPos, buttonsLen do + local button = buttons[i] + if button then + currentSection.db.storedPositions[button.bagID..'-'..button.slotID] = i + end + end + mod:UpdateSection(f, min(buttonsLen, buttonPos), currentSection, layout.numColumns, layout.buttonSize, layout.buttonSpacing) + end + if targetSection then + local buttons = targetSection.buttons + tinsert(buttons, button) + bagMap[slotID] = targetSection + targetSection.db.storedPositions[bagID..'-'..slotID] = #buttons + local rarity = button.rarity or select(3,GetItemInfo(itemID)) + if not layout.filter[rarity] then + button.isHidden = true + button:Hide() + else + mod:UpdateSection(f, #buttons, targetSection, layout.numColumns, layout.buttonSize, layout.buttonSpacing) + end + end + button.shouldEvaluate = nil + elseif f.draggedButton == button then + local currentSection = bagMap[slotID] + if currentSection and button.atHeader then + local targetSection + if button.atHeader == 'evaluate' then + targetSection = (bagType and bagType ~= 0) and currentSection or mod:EvaluateItem(layout.sections, bagID, slotID, itemID) + E:UIFrameFadeOut(f.emptyButton.highlight, 0.2, f.emptyButton.highlight:GetAlpha(), 0) + else + local header = button.atHeader.frame.header + targetSection = button.atHeader + E:UIFrameFadeOut(header.highlight, 0.2, header.highlight:GetAlpha(), 0) + if header.prevEmptySlotsSelection then + f.emptyButton.emptySlotsSelection = header.prevEmptySlotsSelection + header.prevEmptySlotsSelection = nil end - elseif sectionFrame.newUnshown[i] and not itemID then - sectionFrame.occupied[i] = false - sectionFrame.newUnshown[i] = false - minimizedCount = minimizedCount - 1 + end + if targetSection then + local buttonPos = currentSection.db.storedPositions[bagID..'-'..slotID] or 1 + local buttonsT = targetSection.buttons + local buttonsC = currentSection.buttons + for i = buttonPos, #buttonsC do + local button = buttonsC[i] + if button then + currentSection.db.storedPositions[button.bagID..'-'..button.slotID] = i + end + end + tinsert(buttonsT, button) + tremove(buttonsC, buttonPos) + targetSection.db.storedPositions[bagID..'-'..slotID] = #buttonsT + currentSection.db.storedPositions[bagID..'-'..slotID] = nil + bagMap[slotID] = targetSection + mod:UpdateSection(f, min(#buttonsC, buttonPos), currentSection, layout.numColumns, layout.buttonSize, layout.buttonSpacing) + mod:UpdateSection(f, #buttonsT, targetSection, layout.numColumns, layout.buttonSize, layout.buttonSpacing) end end - sectionFrame.title:SetText(section.db.title.text .. (minimizedCount > 0 and " (+" .. minimizedCount .. ")" or "")) - sectionFrame.minimizedCount = max(0, minimizedCount) + button.atHeader = false end - return - end + if oldID and oldID ~= itemID then + itemCounts[oldID] = GetItemCount(oldID) + end + itemCounts[itemID] = itemCount + button.itemID = itemID + end +end - if sectionFrame.expanded then - visibleButtons = #buttons - else - for i, button in ipairs(buttons) do - if button.hasItem then - visibleButtons = i +function mod:UpdateSection(f, index, section, numColumns, buttonSize, buttonSpacing, resize) + local sectionFrame = section.frame + local buttons = section.buttons + local numRows + local sectionHeight = 1 + + if not f.forceShow and #buttons < 1 then + sectionFrame:Hide() + elseif section.db.minimized then + local minimizedCount = 0 + for _, button in ipairs(buttons) do + if button.highlight:IsShown() then + minimizedCount = minimizedCount + 1 end + button:Hide() + button.isHidden = true end - end - - if incombat then - self:UpdateEmptySlotCount(buttons[visibleButtons + 1], 0) - lastEmpty = #buttons + sectionFrame.title:SetText(section.db.title.text..(minimizedCount > 0 and " (+" .. minimizedCount .. ")" or "")) + sectionFrame:Show() else - for i, button in ipairs(buttons) do - local itemID = B_GetItemID(nil, button.bagID, button.slotID) - sectionFrame.occupied[i] = itemID - - if not itemID and i > visibleButtons + 1 then - button:Hide() - else - lastEmpty = i - button:Show() - button.isHidden = false + local pos = index + local buttonPos = section.db.buttonPositions + local isEmpty = true + for i = index, #buttons do + local button = buttons[i] + if button and not button.isHidden then + button:ClearAllPoints() + button:SetPoint("TOPLEFT", section.frame, "TOPLEFT", unpack(buttonPos[pos])) + pos = pos + 1 + isEmpty = false end end - local emptyCount = #buttons - lastEmpty + 1 - if lastEmpty and emptyCount > 0 and not sectionFrame.expanded then - self:UpdateEmptySlotCount(buttons[lastEmpty], emptyCount) + if isEmpty then + if not f.forceShow then + sectionFrame:Hide() + else + sectionFrame:Show() + end + else + numRows = ceil((pos - 1) / section.db.numColumns) + sectionHeight = ceil(numRows * (buttonSize + buttonSpacing) - buttonSpacing) + sectionFrame:Show() end end - if sectionFrame.concatenateButton and sectionFrame.expandButton then - sectionFrame.concatenateButton:ClearAllPoints() - sectionFrame.concatenateButton:Point("TOPLEFT", buttons[lastEmpty], "TOPRIGHT", buttonSpacing, 0) - sectionFrame.expandButton:ClearAllPoints() - sectionFrame.expandButton:Point("BOTTOMLEFT", buttons[lastEmpty], "BOTTOMRIGHT", buttonSpacing, 0) - end - - local numRows = ceil(lastEmpty / section.numColumns) - local totalSectionHeight = sectionHeaderHeight + numRows * (buttonSize + buttonSpacing) - buttonSpacing - sectionFrame.height = totalSectionHeight - - if not incombat then - sectionFrame:Height(totalSectionHeight) - end - - if f.currentLayout and numRows ~= oldNumRows then - self:ResizeFrame(f, buttonSize) - end - - section.numRows = numRows -end - -function mod:SortSection(sortMap, sectionButtons) - for i, info in ipairs(sortMap) do - local targetButton = sectionButtons[i] - local currentItemID = B_GetItemID(nil, targetButton.bagID, targetButton.slotID) - - if currentItemID ~= info.itemID then - for j, button in ipairs(sectionButtons) do - local itemID = B_GetItemID(nil, button.bagID, button.slotID) - if not sortMap[j].positioned and itemID and itemID == info.itemID then - B_PickupItem(nil, button.bagID, button.slotID) - B_PickupItem(nil, targetButton.bagID, targetButton.slotID) - ClearCursor() + sectionFrame:Height(sectionHeight) + sectionFrame.height = sectionHeight - info.bagID = targetButton.bagID - info.slotID = targetButton.slotID - break - end - end - else - info.positioned = true - end - end + if resize or numRows ~= (section.numRows or 0) then + local offsetY = buttonSize/4 + local lastVisibleSection + local currentRowColumns = 0 + local currentRowBottom = 0 - local allPositioned = true - for _, info in ipairs(sortMap) do - if not info.positioned then - allPositioned = false - break - end - end + for _, section in ipairs(f.currentLayout.sections) do + local sectionFrame = section.frame + sectionFrame:ClearAllPoints() - return allPositioned -end + if sectionFrame:IsShown() then + local sectionHeight = sectionFrame.height or sectionFrame:GetHeight() -function mod:StackSection(buttons) - local complete = true - local stacks = {} - for _, button in ipairs(buttons) do - local bagID, slotID = button.bagID, button.slotID - local itemID = B_GetItemID(nil, bagID, slotID) - if itemID then - local stackCount = select(2, B_GetItemInfo(nil, bagID, slotID)) - local _, _, _, _, _, _, _, maxStack = GetItemInfo(itemID) - if not stacks[itemID] then - stacks[itemID] = {} + if not lastVisibleSection then + sectionFrame:Point("TOPLEFT", f.holderFrame, "TOPLEFT", 0, -(offsetY + f.newtopOffset)) + currentRowColumns = section.db.numColumns + currentRowBottom = offsetY + sectionHeight + else + if currentRowColumns + section.db.numColumns <= numColumns then + sectionFrame:Point("TOPLEFT", lastVisibleSection.frame, "TOPRIGHT", buttonSpacing, 0) + currentRowColumns = currentRowColumns + section.db.numColumns + currentRowBottom = max(currentRowBottom, offsetY + sectionHeight) + else + offsetY = currentRowBottom + (section.db.sectionSpacing or 14) + sectionFrame:Point("TOPLEFT", f.holderFrame, "TOPLEFT", 0, -(offsetY + f.newtopOffset)) + currentRowColumns = section.db.numColumns + currentRowBottom = offsetY + sectionHeight + end + end + lastVisibleSection = section end - tinsert(stacks[itemID], {button = button, count = stackCount, maxStack = maxStack}) end - end - for _, stack in pairs(stacks) do - if #stack > 1 then - tsort(stack, function(a, b) return a.count > b.count end) - local targetIndex = 1 - for sourceIndex = 2, #stack do - local target = stack[targetIndex] - local source = stack[sourceIndex] - local spaceInTarget = target.maxStack - target.count - if target.count == target.maxStack then - targetIndex = targetIndex + 1 - end - if spaceInTarget > 0 then - local amountToMove = min(spaceInTarget, source.count) - B_SplitItem(nil, source.button.bagID, source.button.slotID, amountToMove) - B_PickupItem(nil, target.button.bagID, target.button.slotID) - target.count = target.count + amountToMove - source.count = source.count - amountToMove - complete = false - end - end + if lastVisibleSection then + f:Height(f.topOffset + f.bottomOffset + f.newtopOffset + f.newbottomOffset + currentRowBottom - buttonSize/4) + else + f:Height(f.topOffset + f.bottomOffset + f.newtopOffset + f.newbottomOffset) end + section.numRows = numRows end - - return complete -end - -function mod:UpdateEmptySlotCount(button, count) - if not button then return end - - if count > 1 then - button.Count:SetText(count) - button.Count:Show() - elseif not button.count or button.count < 2 then - button.Count:Hide() - end end function mod:SetSlotAlphaForBag(self, f) @@ -1965,36 +2811,68 @@ function mod:ResetSlotAlphaForBags(self, f) end end -function mod:BagsExtended(db) - if db.BagsExtended.enabled then - E.db.bags.reverseSlots = false - for _, func in pairs({'Layout', 'UpdateSlot', 'UpdateBagSlots', 'SetSlotAlphaForBag', 'ResetSlotAlphaForBags'}) do - if not self:IsHooked(B, func) then self:SecureHook(B, func) end - end - if E.Options.args.bags then - E.Options.args.bags.args.general.args.reverseSlots.hidden = true - else - if not self:IsHooked(E, 'ToggleOptionsUI') then - self:SecureHook(E, 'ToggleOptionsUI', function() - if not E.Options.args.bags then return end - E.Options.args.bags.args.general.args.reverseSlots.hidden = true - E:RefreshGUI() - end) +function mod:BagsExtendedV2(db) + if db.BagsExtendedV2.enabled then + self:Unhook(B, 'Layout') + self:SecureHook(B, 'Layout', function(self, isBank) + mod:Unhook(B, 'Layout') + mod:Layout(self, isBank) + for _, func in ipairs({'Layout', 'UpdateSlot', 'SetSlotAlphaForBag', 'ResetSlotAlphaForBags'}) do + if not mod:IsHooked(B, func) then mod:SecureHook(B, func) end end + end) + if not self:IsHooked(E, 'ToggleOptionsUI') then + self:SecureHook(E, 'ToggleOptionsUI', function() + if not E.Options.args.bags then + return + end + E:RefreshGUI() + end) + end + if not self:IsHooked("EquipmentManager_EquipSet") then + self:SecureHook("EquipmentManager_EquipSet", function(setName) + local locations = GetEquipmentSetLocations(setName) + if locations then + for _, location in pairs(locations) do + if location then + local _, bank, bags, slot, bag = EquipmentManager_UnpackLocation(location) + if bank then + local f = B_GetContainerFrame(nil, true) + local button = f and f.Bags[-1] and f.Bags[-1][slot-39] + if button then + button.shouldEvaluate = true + end + elseif bags then + local f = B_GetContainerFrame(nil, bag < 0 or bag > NUM_BAG_SLOTS) + local button = f and f.Bags[bag] and f.Bags[bag][slot] + if button then + button.shouldEvaluate = true + end + end + end + end + end + end) end - self:RegisterEvent("PLAYER_REGEN_DISABLED", function() incombat = true updateLayouts() end) - self:RegisterEvent("PLAYER_REGEN_ENABLED", function() incombat = false updateLayouts() end) self:UpdateAll() - initialized.BagsExtended = true - elseif initialized.BagsExtended then - if E.Options.args.bags then E.Options.args.bags.args.general.args.reverseSlots.hidden = false end - if self:IsHooked(E, 'ToggleOptionsUI') then self:Unhook(E, 'ToggleOptionsUI') end - for _, func in pairs({'Layout', 'UpdateSlot', 'UpdateBagSlots', 'SetSlotAlphaForBag', 'ResetSlotAlphaForBags'}) do + self:RegisterEvent("EQUIPMENT_SETS_CHANGED", updateSetsInfo) + self:RegisterEvent("EQUIPMENT_SWAP_FINISHED", updateSetsInfo) + initialized.BagsExtendedV2 = true + elseif initialized.BagsExtendedV2 then + for _, func in pairs({'UpdateSlot', 'SetSlotAlphaForBag', 'ResetSlotAlphaForBags'}) do if self:IsHooked(B, func) then self:Unhook(B, func) end end + if self:IsHooked(B, 'Layout') and not (db.EasierProcessing.enabled or db.SplitStack.enabled) then + self:Unhook(B, 'Layout') + end + if self:IsHooked(E, 'ToggleOptionsUI') then + self:Unhook(E, 'ToggleOptionsUI') + end self:UpdateAll(true) - initialized.BagsExtended = false + self:UnregisterEvent("EQUIPMENT_SETS_CHANGED") + self:UnregisterEvent("EQUIPMENT_SWAP_FINISHED") + initialized.BagsExtendedV2 = false end end @@ -2088,24 +2966,41 @@ function mod:Process(self, modifier) local x, y = self:GetCenter() ProcessButton:Point("CENTER", UIParent, "BOTTOMLEFT", x, y + self:GetHeight()) ProcessButton:Show() + ProcessButton:SetScript("OnUpdate", function() + ProcessButton:ClearAllPoints() + x, y = self:GetCenter() + ProcessButton:Point("CENTER", UIParent, "BOTTOMLEFT", x, y + self:GetHeight()) + end) end end end -function mod:FindEmpty(isBagsExtended, bagSpace) - if isBagsExtended then - for _, button in ipairs(bagSpace.buttons) do - local bagID, slotID = button.bagID, button.slotID - if not B_GetItemInfo(nil, bagID, slotID) then - return bagID, slotID +function mod:FindEmpty(isBagsExtendedV2, bagSpace, bagID) + if isBagsExtendedV2 then + for i, button in ipairs(bagSpace.buttons) do + if not button.hasItem then + return button, button.bagID, button.slotID, i end end else - for _, bagID in ipairs(bagSpace.BagIDs) do - if bagSpace.Bags[bagID] and bagSpace.Bags[bagID].numSlots > 0 then - for slotID = 1, GetContainerNumSlots(bagID) do - if not B_GetItemInfo(nil, bagID, slotID) then - return bagID, slotID + local targetBag = bagSpace.Bags[bagID] + if targetBag and targetBag.numSlots > 0 then + for slotID = 1, targetBag.numSlots do + local button = targetBag[slotID] + if button and not button.hasItem then + return button, bagID, slotID, slotID + end + end + else + for _, bagID in ipairs(bagSpace.BagIDs) do + local bag = bagSpace.Bags[bagID] + local bagSlots = bag and bag.numSlots + if bagSlots and bagSlots > 0 and (not bag.type or bag.type == 0) then + for slotID = 1, bagSlots do + local button = bag[slotID] + if button and not button.hasItem then + return button, bagID, slotID, slotID + end end end end @@ -2115,21 +3010,27 @@ end function mod:SplitHandler(self, button) local modifier = E.db.Extras.general[modName].SplitStack.modifier - local isBagsExtended = E.db.Extras.general[modName].BagsExtended.enabled + local isBagsExtendedV2 = E.db.Extras.general[modName].BagsExtendedV2.enabled if IsModifierKeyDown() and (modifier == 'ANY' or _G['Is'..modifier..'KeyDown']()) then local bagID, slotID = self.bagID, self.slotID - local bagSpace = isBagsExtended and buttonMap[bagID][slotID] or B_GetContainerFrame(nil, bagID < 0 or bagID > NUM_BAG_SLOTS) - - if not bagSpace then return end + local f = B_GetContainerFrame(nil, bagID < 0 or bagID > NUM_BAG_SLOTS) if button == 'LeftButton' then local stackCount = select(2, B_GetItemInfo(nil, bagID, slotID)) if not stackCount or stackCount == 1 then return end - local split = floor(stackCount / 2) - local freeBagID, freeSlotID = mod:FindEmpty(isBagsExtended, bagSpace) + local _, freeBagID, freeSlotID + if isBagsExtendedV2 then + local section = buttonMap[bagID][slotID] + local emptyButton = section.isSpecialBag and mod:FindEmpty(nil, f, section.bagID) or next(buttonMap[f]) + if emptyButton then + freeBagID, freeSlotID = emptyButton.bagID, emptyButton.slotID + end + else + _, freeBagID, freeSlotID = mod:FindEmpty(nil, f) + end if freeSlotID then B_SplitItem(nil, bagID, slotID, split) B_PickupItem(nil, freeBagID, freeSlotID) @@ -2137,26 +3038,31 @@ function mod:SplitHandler(self, button) print(core.customColorBad..ERR_SPLIT_FAILED) end elseif button == 'RightButton' then - if not self.isStacking then + local handler = f.SplitStackHandler + if not handler.isStacking then local itemID = B_GetItemID(nil, bagID, slotID) if not itemID then return end - self.isStacking = true + handler.isStacking = true local timeElapsed, partialStacks = 0, {} - if isBagsExtended then - for _, button in ipairs(bagSpace.buttons) do - local buttonBagID, buttonSlotID = button.bagID, button.slotID - if B_GetItemID(nil, buttonBagID, buttonSlotID) == itemID then - tinsert(partialStacks, button) - end - end + if isBagsExtendedV2 then + local section = buttonMap[bagID][slotID] + if section then + for _, button in ipairs(section.buttons) do + if B_GetItemID(nil, button.bagID, button.slotID) == itemID then + tinsert(partialStacks, button) + end + end + end else - for _, bagID in ipairs(bagSpace.BagIDs) do - if bagSpace.Bags[bagID] and bagSpace.Bags[bagID].numSlots > 0 then - for slotID = 1, GetContainerNumSlots(bagID) do - if bagSpace.Bags[bagID][slotID] and B_GetItemID(nil, bagID, slotID) == itemID then - tinsert(partialStacks, bagSpace.Bags[bagID][slotID]) + for _, bagID in ipairs(f.BagIDs) do + local bag = f.Bags[bagID] + if bag and bag.numSlots > 0 then + for slotID = 1, bag.numSlots do + local bagButton = bag[slotID] + if bagButton and B_GetItemID(nil, bagID, slotID) == itemID then + tinsert(partialStacks, bagButton) end end end @@ -2164,8 +3070,20 @@ function mod:SplitHandler(self, button) end if #partialStacks == 0 then return end - local stacked, positioned - self:SetScript('OnUpdate', function(self, elapsed) + local stacks = {} + for _, button in ipairs(partialStacks) do + local bagID, slotID = button.bagID, button.slotID + local itemID = B_GetItemID(nil, bagID, slotID) + if itemID then + local stackCount = select(2, B_GetItemInfo(nil, bagID, slotID)) + local _, _, _, _, _, _, _, maxStack = GetItemInfo(itemID) + if not stacks[itemID] then + stacks[itemID] = {} + end + tinsert(stacks[itemID], {button = button, count = stackCount, maxStack = maxStack}) + end + end + handler:SetScript('OnUpdate', function(self, elapsed) timeElapsed = timeElapsed + elapsed if timeElapsed > 0.1 then if InCombatLockdown() then @@ -2176,32 +3094,38 @@ function mod:SplitHandler(self, button) end timeElapsed = 0 - stacked = mod:StackSection(partialStacks) - ClearCursor() - - if stacked then - positioned = true - for i = #partialStacks, 1, -1 do - local button = partialStacks[i] - local buttonBagID, buttonSlotID = button.bagID, button.slotID - local buttonItemID = B_GetItemID(nil, buttonBagID, buttonSlotID) - if buttonItemID then - local freeBagID, freeSlotID = mod:FindEmpty(isBagsExtended, bagSpace) - if freeBagID and freeSlotID and (freeBagID ~= buttonBagID or freeSlotID < buttonSlotID) then - B_PickupItem(nil, buttonBagID, buttonSlotID) - B_PickupItem(nil, freeBagID, freeSlotID) - positioned = false - break + local complete = true + for _, stack in pairs(stacks) do + if #stack > 1 then + tsort(stack, function(a, b) return a.count > b.count end) + local targetIndex = 1 + for sourceIndex = 2, #stack do + local target = stack[targetIndex] + local source = stack[sourceIndex] + if source.count >= 0 then + local spaceInTarget = target.maxStack - target.count + while targetIndex < sourceIndex and target.count >= target.maxStack do + targetIndex = targetIndex + 1 + target = stack[targetIndex] + spaceInTarget = target.maxStack - target.count + end + if source.button ~= target.button and spaceInTarget > 0 and source.count > 0 then + local amountToMove = min(spaceInTarget, source.count) + B_SplitItem(nil, source.button.bagID, source.button.slotID, amountToMove) + B_PickupItem(nil, target.button.bagID, target.button.slotID) + target.count = target.count + amountToMove + source.count = source.count - amountToMove + ClearCursor() + complete = false + break + end end - else - tremove(partialStacks, i) end end - - if positioned or #partialStacks == 0 then - self.isStacking = false - self:SetScript('OnUpdate', nil) - end + end + if complete then + self.isStacking = false + self:SetScript('OnUpdate', nil) end end end) @@ -2293,7 +3217,11 @@ function mod:EasierProcessing(db) self.ProcessButton = self.ProcessButton and self.ProcessButton or self:CreateProcessingButton() self.localhooks.EasierProcessing = { ["OnClick"] = function(self) mod:Process(self, db.EasierProcessing.modifier) end, - ["OnHide"] = function() if self.ProcessButton:IsShown() then self.ProcessButton:Hide() end end + ["OnHide"] = function() if self.ProcessButton:IsShown() then + self.ProcessButton:Hide() + self.ProcessButton:SetScript("OnUpdate", nil) + end + end } self:Hide() self = nil @@ -2302,13 +3230,19 @@ function mod:EasierProcessing(db) self.ProcessButton = self.ProcessButton and self.ProcessButton or self:CreateProcessingButton() self.localhooks.EasierProcessing = { ["OnClick"] = function(self) mod:Process(self, db.EasierProcessing.modifier) end, - ["OnHide"] = function() if self.ProcessButton:IsShown() then self.ProcessButton:Hide() end end + ["OnHide"] = function() if self.ProcessButton:IsShown() then + self.ProcessButton:Hide() + self.ProcessButton:SetScript("OnUpdate", nil) + end + end } end initialized.EasierProcessing = true elseif initialized.EasierProcessing then - if self:IsHooked(B, 'Layout') and not (db.BagsExtended.enabled or db.SplitStack.enabled) then self:Unhook(B, 'Layout') end + if self:IsHooked(B, 'Layout') and not (db.BagsExtendedV2.enabled or db.SplitStack.enabled) then + self:Unhook(B, 'Layout') + end self.localhooks.EasierProcessing["OnClick"] = false self.localhooks.EasierProcessing["OnHide"] = false self.ProcessButton:Hide() @@ -2328,7 +3262,9 @@ function mod:SplitStack(db) self:ModifyStackSplitFrame(true) initialized.SplitStack = true elseif initialized.SplitStack then - if self:IsHooked(B, 'Layout') and not (db.BagsExtended.enabled or db.EasierProcessing.enabled) then self:Unhook(B, 'Layout') end + if self:IsHooked(B, 'Layout') and not (db.BagsExtendedV2.enabled or db.EasierProcessing.enabled) then + self:Unhook(B, 'Layout') + end self.localhooks.SplitStack["OnClick"] = false self:ModifyStackSplitFrame(false) initialized.SplitStack = false @@ -2337,9 +3273,16 @@ end function mod:Toggle(db) - self:EasierProcessing(db) - self:SplitStack(db) - self:BagsExtended(db) + if core.reload then + local reload = {BagsExtendedV2 = {}, EasierProcessing = {}, SplitStack = {}} + self:BagsExtendedV2(reload) + self:EasierProcessing(reload) + self:SplitStack(reload) + else + self:BagsExtendedV2(db) + self:EasierProcessing(db) + self:SplitStack(db) + end end function mod:InitializeCallback() @@ -2349,4 +3292,4 @@ function mod:InitializeCallback() mod:Toggle(E.db.Extras.general[modName]) end -core.modules[modName] = mod.InitializeCallback +core.modules[modName] = mod.InitializeCallback \ No newline at end of file diff --git a/Modules/General/Chat.lua b/Modules/General/Chat.lua index 7c1ae8c..b47f814 100644 --- a/Modules/General/Chat.lua +++ b/Modules/General/Chat.lua @@ -297,8 +297,7 @@ local function setupHooks(db) return end - local tokens = mod:Tokenize(query) - local queryTree = mod:ParseExpression(tokens) + local queryTree = mod:ParseExpression(mod:Tokenize(query)) local highlight_patterns = {} local validType = frame.searchArgs["LIVE"] @@ -350,8 +349,7 @@ local function setupHooks(db) return end - local tokens = mod:Tokenize(query) - local queryTree = mod:ParseExpression(tokens) + local queryTree = mod:ParseExpression(mod:Tokenize(query)) local highlight_patterns = {} local validType = frame.searchArgs["LIVE"] @@ -453,9 +451,11 @@ local function setupHooks(db) end local function setupSearchFilter(db) - hlR, hlG, hlB = unpack(db.highlightColor) - prompts, queries = db.prompts, db.queries - historyIndex = #prompts + if not core.reload then + hlR, hlG, hlB = unpack(db.highlightColor) + prompts, queries = db.prompts, db.queries + historyIndex = #prompts + end for i = 1, NUM_CHAT_WINDOWS do local frame = _G["ChatFrame"..i] @@ -467,6 +467,8 @@ local function setupSearchFilter(db) ["rules"] = { { ["terms"] = "", + ["queryTree"] = {}, + ["parsedExpression"] = {}, ["types"] = {}, ["blacklist"] = true, }, @@ -474,7 +476,10 @@ local function setupSearchFilter(db) } frame.filterRules = db.frames[i].rules - + for _, rule in ipairs(db.frames[i].rules) do + rule.queryTree = mod:Tokenize(rule.terms) + rule.parsedExpression = mod:ParseExpression(rule.queryTree) + end if not frame.searchBar then blockedMsgs[frame] = {} savedChatState[frame] = {} @@ -568,13 +573,13 @@ local function setupSearchFilter(db) end end) - local chatTypes = { "LIVE", "HISTORY", "ALL", "SAY", "YELL", "PARTY", "RAID", "BATTLEGROUND", "GUILD", "WHISPER", "CHANNEL", "OTHER" } - local function initializeConfigDropdown(self, level) if not level then return end if level == 1 then - for j, event in ipairs(chatTypes) do + for j, event in ipairs({"LIVE", "HISTORY", "ALL", + "SAY", "YELL", "PARTY", "RAID", + "BATTLEGROUND", "GUILD", "WHISPER", "CHANNEL", "OTHER" }) do if j <= 3 or not frame.searchArgs["ALL"] then local info = UIDropDownMenu_CreateInfo() info.text = event == "LIVE" and L["Live"] or event == "HISTORY" and L["History"] or event == "ALL" and L["All"] or localizedTypes[event] @@ -599,8 +604,8 @@ local function setupSearchFilter(db) mod:PerformSearch(frame, frame.searchBar:GetText()) end CloseDropDownMenus() - local button = self:GetParent() - ToggleDropDownMenu(1, nil, button.configDropdown, button, 0, 0) + local searchButton = self:GetParent() + ToggleDropDownMenu(1, nil, searchButton.configDropdown, searchButton, 0, 0) end info.value = event UIDropDownMenu_AddButton(info, level) @@ -632,8 +637,8 @@ local function setupSearchFilter(db) if IsShiftKeyDown() then saveQuery(i) CloseDropDownMenus() - local button = self:GetParent() - ToggleDropDownMenu(1, nil, button.historyDropdown, button, 0, 0) + local searchButton = self:GetParent() + ToggleDropDownMenu(1, nil, searchButton.historyDropdown, searchButton, 0, 0) else local query = recentQueries[i] local searchBar = frame.searchBar @@ -666,8 +671,8 @@ local function setupSearchFilter(db) if IsShiftKeyDown() then deleteQuery(i) CloseDropDownMenus() - local button = self:GetParent() - ToggleDropDownMenu(1, nil, button.historyDropdown, button, 0, 0) + local searchButton = self:GetParent() + ToggleDropDownMenu(1, nil, searchButton.historyDropdown, searchButton, 0, 0) else local query = queries[i].query local searchBar = frame.searchBar @@ -815,8 +820,8 @@ local function setupCompactChat(db) db.selectedLeftTab = id end - local alertingTabs = alertingTabs[(isRightSide and 'right' or 'left')] - alertingTabs[id] = nil + local alertTabs = alertingTabs[(isRightSide and 'right' or 'left')] + alertTabs[id] = nil if not next(alertingTabs) then local button = (isRightSide and RightChatPanel or LeftChatPanel).tabManagerButton @@ -933,9 +938,9 @@ local function setupCompactChat(db) button.highlightTexture:SetAlpha(0) end - local alertingTabs = isRightSide and alertingTabs.right or alertingTabs.left + local alertTabs = isRightSide and alertingTabs.right or alertingTabs.left - if alertingTabs[id] then + if alertTabs[id] then if not tcontains(flashingButtons, button.highlightTexture) then UIFrameFlash(button.highlightTexture, 1.0, 1.0, -1, false, 0, 0, "chat") tinsert(flashingButtons, button.highlightTexture) @@ -1211,16 +1216,18 @@ local function setupCompactChat(db) local tab = _G[format("%sTab", frameName)] if (id <= NUM_CHAT_WINDOWS) then - local isRightChatTab = isRightChatTab(chat) + local isRight = isRightChatTab(chat) local parentFrame - if isRightChatTab then + if isRight then parentFrame = RightChatPanel else parentFrame = LeftChatPanel end - local offset = ((isRightChatTab and E.db.datatexts.rightChatPanel) or (not isRightChatTab and E.db.datatexts.leftChatPanel)) and E.Border*3 - E.Spacing + 22 or 0 + local offset = ((isRight and E.db.datatexts.rightChatPanel) + or (not isRight and E.db.datatexts.leftChatPanel)) and E.Border*3 - E.Spacing + 22 + or 0 chat:ClearAllPoints() chat:Point("TOPLEFT", parentFrame, "TOPLEFT", db.leftOffset, -db.topOffset) @@ -1394,7 +1401,9 @@ local function setupCompactChat(db) chatFrame:ClearAllPoints() chatFrame:Point("TOPLEFT", GeneralDockManager, "BOTTOMLEFT", 0, -6) chatFrame:Point("TOPRIGHT", GeneralDockManager, "BOTTOMRIGHT", 0, -6) - break + end + if mod:IsHooked(chatFrame, "OnUpdate") then + mod:Unhook(chatFrame, "OnUpdate") end end @@ -1403,7 +1412,9 @@ local function setupCompactChat(db) buttonTex:SetAlpha(0) end - CH:UpdateAnchors() + if not core.reload then + CH:UpdateAnchors() + end end if not initialized.compactChat then return end @@ -1467,6 +1478,8 @@ P["Extras"]["general"][modName] = { ["rules"] = { { ["terms"] = "", + ["queryTree"] = {}, + ["parsedExpression"] = {}, ["types"] = {}, ["blacklist"] = true, }, @@ -1716,7 +1729,12 @@ function mod:LoadConfig() desc = "", func = function() local frameRules = db.SearchFilter.frames[selectedFrame()].rules - tinsert(frameRules, { ["terms"] = "", ["blacklist"] = true, ["types"] = {}}) + tinsert(frameRules, { ["terms"] = "", + ["queryTree"] = "", + ["parsedExpression"] = {}, + ["blacklist"] = true, + ["types"] = {} + }) db.SearchFilter.frames[selectedFrame()].selectedRule = #frameRules self:Toggle(db) end, @@ -1855,12 +1873,9 @@ function mod:FilterNotPassed(frame, msg, chatType) chatType = chatTypes[chatType] and chatType or "OTHER" local cleanMsg = mod:StripMsg(msg) - local frameRules = frame.filterRules - for _, info in ipairs(frameRules) do + for _, info in ipairs(frame.filterRules) do if (info.types["ALL"] or info.types[chatType]) then - local tokens = mod:Tokenize(info.terms) - local queryTree = mod:ParseExpression(tokens) - local matched = mod:MatchPattern(queryTree, nil, cleanMsg, lower(cleanMsg)) + local matched = mod:MatchPattern(info.parsedExpression, nil, cleanMsg, lower(cleanMsg)) if (info.blacklist and matched) or (not info.blacklist and not matched) then return true end @@ -1985,7 +2000,7 @@ function mod:StripMsg(msg) local strippedMsg, msgMap = "", {} local i, j = 1, 1 local tempMsg = lower(msg) - local len = #tempMsg + local strLen = #tempMsg local colorPattern = "^|c%x%x%x%x%x%x%x%x" local linkPattern = "(.-|h)(.-)|h" @@ -1999,7 +2014,7 @@ function mod:StripMsg(msg) end -- strip junk text and store real positions - while i <= len do + while i <= strLen do local b1, b2 = byte(tempMsg, i, i+1) if b1 == 124 then -- '|, code start' @@ -2120,16 +2135,16 @@ function mod:HighlightText(msg, cleanMsg, cleanMsgLower, msgMap, terms) tsort(matches, function(a, b) return a[1] < b[1] end) local currentRange = nil - for _, match in ipairs(matches) do + for _, matchVal in ipairs(matches) do if currentRange then - if match[1] <= currentRange[2] + 1 then - currentRange[2] = max(currentRange[2], match[2]) + if matchVal[1] <= currentRange[2] + 1 then + currentRange[2] = max(currentRange[2], matchVal[2]) else tinsert(ranges, currentRange) - currentRange = {match[1], match[2]} + currentRange = {matchVal[1], matchVal[2]} end else - currentRange = {match[1], match[2]} + currentRange = {matchVal[1], matchVal[2]} end end @@ -2222,8 +2237,7 @@ function mod:PerformSearch(frame, query) twipe(searchResults) - local tokens = self:Tokenize(query) - local queryTree = self:ParseExpression(tokens) + local queryTree = self:ParseExpression(self:Tokenize(query)) local displayingFiltered = frame.displayingFiltered local lastHistoryMsg = (not displayingFiltered and lastHisoryMsgIndex[frame] and not frame.searchArgs["HISTORY"]) and lastHisoryMsgIndex[frame] or -1 local targetTable = (displayingFiltered and filteredMsgs[frame].processed) or (not displayingFiltered and savedChatState[frame]) @@ -2255,16 +2269,16 @@ function mod:PerformSearch(frame, query) self:DisplaySearchResults(frame, searchResults, query) end -function mod:DisplaySearchResults(frame, searchResults, query) +function mod:DisplaySearchResults(frame, results, query) frame.displayingSearchResults = true frame:Clear() - for _, msg in ipairs(searchResults) do + for _, msg in ipairs(results) do frame:AddMessage(msg) end - if #searchResults == 0 then + if #results == 0 then frame:AddMessage("No results found.", rBad, gBad, bBad) frame.searchNoResults = true end @@ -2313,7 +2327,7 @@ function mod:InitializeCallback() bBad = tonumber(sub(hex, 5, 6), 16) / 255 mod:LoadConfig() - mod:Toggle(E.db.Extras.general[modName]) + mod:Toggle(core.reload and {SearchFilter = {}, CompactChat = {}, ChatEditBox = {}} or E.db.Extras.general[modName]) end -core.modules[modName] = mod.InitializeCallback +core.modules[modName] = mod.InitializeCallback \ No newline at end of file diff --git a/Modules/General/CustomCommands.lua b/Modules/General/CustomCommands.lua index 2536eb0..8e9db70 100644 --- a/Modules/General/CustomCommands.lua +++ b/Modules/General/CustomCommands.lua @@ -3,16 +3,15 @@ local core = E:GetModule("Extras") local mod = core:NewModule("Custom Commands", "AceHook-3.0") local modName = mod:GetName() -local errorCount, lastEventTime = 0 +local lastEventTime = {} local handler = CreateFrame("Frame") local initialized local tostring, tonumber = tostring, tonumber local pairs, ipairs, loadstring, pcall, print, select = pairs, ipairs, loadstring, pcall, print, select local tinsert, tremove = table.insert, table.remove -local sub, find, gsub, upper, format = string.sub, string.find, string.gsub, string.upper, string.format +local sub, find, upper, match, gmatch = string.sub, string.find, string.upper, string.match, string.gmatch local GetTime = GetTime -local INTERRUPTED = INTERRUPTED local function convertToValue(value) if value == 'nil' then @@ -30,17 +29,18 @@ end P["Extras"]["general"][modName] = { ["enabled"] = false, ["selected"] = 1, - ["tabs"] = {{ name = L["New Tab"], events = "", commands = "", throttleEvents = {}, selectedEvent = '', enabled = true }}, + ["tabs"] = {{ name = L["New Tab"], events = "", commands = "", throttleEvents = {}, selectedEvent = '', enabled = true, preLoad = false }}, ["conditions"] = {}, ["commands"] = {}, } function mod:LoadConfig() + local db = E.db.Extras.general[modName] core.general.args[modName] = { type = "group", name = L[modName], - get = function(info) return E.db.Extras.general[modName][info[#info]] end, - set = function(info, value) E.db.Extras.general[modName][info[#info]] = value mod:Toggle(value) end, + get = function(info) return db[info[#info]] end, + set = function(info, value) db[info[#info]] = value self:Toggle(db) end, args = { CustomCommands = { order = 1, @@ -62,15 +62,24 @@ function mod:LoadConfig() type = "group", name = L["Settings"], guiInline = true, - disabled = function() return not E.db.Extras.general[modName].enabled end, + disabled = function() return not db.enabled end, args = { enableTab = { - order = 2, + order = 1, type = "toggle", + width = "full", name = L["Enable Tab"], desc = "", - get = function() return E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].enabled end, - set = function(_, value) E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].enabled = value self:SetupHandler() end, + get = function() return db.tabs[db.selected].enabled end, + set = function(_, value) db.tabs[db.selected].enabled = value self:SetupHandler(db) end, + }, + preLoad = { + order = 2, + type = "toggle", + name = L["Pre-Load"], + desc = L["Executes commands during the addon's initialization process."], + get = function() return db.tabs[db.selected].preLoad end, + set = function(_, value) db.tabs[db.selected].preLoad = value end, }, throttleTime = { order = 3, @@ -78,20 +87,20 @@ function mod:LoadConfig() min = 0, max = 600, step = 0.1, name = L["Throttle Time"], desc = L["Minimal time gap between two consecutive executions."], - get = function() return E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].throttleEvents[E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].selectedEvent] or 0.3 end, - set = function(_, value) E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].throttleEvents[E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].selectedEvent] = value end, - disabled = function() return not E.db.Extras.general[modName].enabled or E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].selectedEvent == '' end, + get = function() return db.tabs[db.selected].throttleEvents[db.tabs[db.selected].selectedEvent] or 0.3 end, + set = function(_, value) db.tabs[db.selected].throttleEvents[db.tabs[db.selected].selectedEvent] = value end, + disabled = function() return not db.enabled or db.tabs[db.selected].selectedEvent == '' or db.tabs[db.selected].preLoad end, }, tabSelection = { order = 4, type = "select", name = L["Select Tab"], desc = "", - get = function() return tostring(E.db.Extras.general[modName].selected) end, - set = function(_, value) E.db.Extras.general[modName].selected = tonumber(value) end, + get = function() return tostring(db.selected) end, + set = function(_, value) db.selected = tonumber(value) end, values = function() local dropdownValues = {} - for i, tab in ipairs(E.db.Extras.general[modName].tabs) do + for i, tab in ipairs(db.tabs) do dropdownValues[tostring(i)] = tab.name end return dropdownValues @@ -102,11 +111,11 @@ function mod:LoadConfig() type = "select", name = L["Select Event"], desc = "", - get = function() return E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].selectedEvent end, - set = function(_, value) E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].selectedEvent = value end, + get = function() return db.tabs[db.selected].selectedEvent end, + set = function(_, value) db.tabs[db.selected].selectedEvent = value end, values = function() local dropdownValues = {} - for event in pairs(E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].throttleEvents) do + for event in pairs(db.tabs[db.selected].throttleEvents) do dropdownValues[tostring(event)] = event end return dropdownValues @@ -121,7 +130,7 @@ function mod:LoadConfig() get = function() return "" end, set = function(_, value) if value and value ~= "" then - E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].name = value + db.tabs[db.selected].name = value end end, }, @@ -131,9 +140,18 @@ function mod:LoadConfig() name = L["Add Tab"], desc = "", func = function() - local newTab = { name = L["New Tab"], events = "", commands = "", throttleTime = 0.3, throttleEvents = {}, selectedEvent = '', enabled = true } - tinsert(E.db.Extras.general[modName].tabs, newTab) - E.db.Extras.general[modName].selected = #E.db.Extras.general[modName].tabs + local newTab = { + name = L["New Tab"], + events = "", + commands = "", + throttleTime = 0.3, + throttleEvents = {}, + selectedEvent = '', + enabled = true, + preLoad = false, + } + tinsert(db.tabs, newTab) + db.selected = #db.tabs end, }, deleteTab = { @@ -141,8 +159,8 @@ function mod:LoadConfig() type = "execute", name = L["Delete Tab"], desc = "", - func = function() tremove(E.db.Extras.general[modName].tabs, E.db.Extras.general[modName].selected) E.db.Extras.general[modName].selected = 1 end, - disabled = function() return #E.db.Extras.general[modName].tabs <= 1 or not E.db.Extras.general[modName].enabled end, + func = function() tremove(db.tabs, db.selected) db.selected = 1 end, + disabled = function() return #db.tabs <= 1 or not db.enabled end, }, openEditFrame = { order = 9, @@ -151,10 +169,12 @@ function mod:LoadConfig() name = L["Open Edit Frame"], desc = "", func = function() - local db = E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected] - core:OpenEditor(L["Custom Commands"], db.commands, function() db.commands = core.EditFrame.editBox:GetText() mod:SetupHandler() end) + local tab_db = db.tabs[db.selected] + core:OpenEditor(L["Custom Commands"], + tab_db.commands, + function() tab_db.commands = core.EditFrame.editBox:GetText() mod:SetupHandler(tab_db) end) end, - disabled = function() return not E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].enabled or not E.db.Extras.general[modName].enabled end, + disabled = function() return not db.tabs[db.selected].enabled or not db.enabled end, }, eventsEditbox = { order = 10, @@ -163,9 +183,9 @@ function mod:LoadConfig() width = "double", name = L["Events"], desc = L["UNIT_AURA CHAT_MSG_WHISPER etc.\nONUPDATE - 'OnUpdate' script"], - get = function() return E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].events and E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].events or "" end, - set = function(_, value) E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].events = value self:SetupHandler() end, - disabled = function() return not E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].enabled or not E.db.Extras.general[modName].enabled end, + get = function() return db.tabs[db.selected].events and db.tabs[db.selected].events or "" end, + set = function(_, value) db.tabs[db.selected].events = value self:SetupHandler(db) end, + disabled = function() return not db.tabs[db.selected].enabled or not db.enabled or db.tabs[db.selected].preLoad end, }, commandsEditbox = { order = 11, @@ -179,7 +199,7 @@ function mod:LoadConfig() "\n[k~=@@UnitName('player')]".. "\n@@@commands@@@".. "\n\n'EVENT' - Event from the events section above".. - "\n'n, m, k' - indexex of the desired payload args (number)".. + "\n'n, m, k' - indexes of the desired payload args (number)".. "\n'nil/value/boolean/lua code' - desired output of n arg".. "\n'@@' - lua arg flag, must go before the lua code within the args' value section".. "\n'~' - negate flag, add before the equals sign to have the code executed if n/m/k is not mathing the set value instead".. @@ -189,22 +209,25 @@ function mod:LoadConfig() "\n\nUNIT_AURA[1=player]@@@".. "\nprint(player has gained/lost an aura)@@@".. "\n\nCHAT_MSG_WHISPER".. - "\n[5~=UnitName('player')]".. + "\n[5~=@@UnitName('player')]".. "\n[14=false]@@@".. "\nPlaySound('LEVELUPSOUND', 'master')@@@".. "\n\nCOMBAT_LOG_EVENT_".. "\nUNFILTERED".. - "\n[5=UnitName('arena1')]".. - "\n[5=UnitName('arena2')]@@@".. + "\n[5=@@UnitName('arena1')]".. + "\n[5=@@UnitName('arena2')]@@@".. "\nfor i = 1, 2 do".. "\nif UnitDebuff('party'..i, 'Bad Spell')".. "\nthen print(UnitName('party'..i)..' is afflicted!')".. "\nend end@@@".. "\n\nThis module parses strings, so try to have your code follow the syntax strictly, or else it might not work."], width = "double", - get = function() local storedValue = E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].commands ~= "" and E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].commands return storedValue end, - set = function(_, value) E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].commands = value mod:SetupHandler() end, - disabled = function() return not E.db.Extras.general[modName].tabs[E.db.Extras.general[modName].selected].enabled or not E.db.Extras.general[modName].enabled end, + get = function() + local storedValue = db.tabs[db.selected].commands ~= "" and db.tabs[db.selected].commands + return storedValue + end, + set = function(_, value) db.tabs[db.selected].commands = value mod:SetupHandler(db) end, + disabled = function() return not db.tabs[db.selected].enabled or not db.enabled end, }, }, }, @@ -213,202 +236,183 @@ function mod:LoadConfig() end -function mod:LoadCommands(commands, eventArg, tabArg, ...) - if not commands then - if errorCount >= 10 then - mod:Toggle(false) - return - end - errorCount = errorCount + 1 - core:print('FORMATTING', L["CustomCommands"], '') - return - end - - local luaFunction, errorMsg = loadstring("return function(...) "..commands.." end") - if luaFunction then - local success, fn = pcall(luaFunction) - if not success then - core:print('FAIL', L["CustomCommands"], fn) - return - end - - local result - if tabArg then - local wrapperFunction = function() - local evaluatedTabArg = loadstring("return "..tabArg)() - return pcall(fn, eventArg, evaluatedTabArg) - end - success, result = wrapperFunction() - if not success then - core:print('FAIL', L["CustomCommands"], result) +function mod:CheckArgs(tab, ...) + for _, argTab in ipairs(tab.args) do + local eventArg = select(argTab.index, ...) + if argTab.argIsLua then + -- Check the lua arg using the cached function + local result = argTab.argFunc() == eventArg + + if (result and argTab.negate) or (not result and not argTab.negate) then + return true end - return result else - success, result = pcall(fn, ...) - if not success then - core:print('FAIL', L["CustomCommands"], result) + if (not argTab.negate and argTab.arg ~= eventArg) + or (argTab.negate and argTab.arg == eventArg) then + return true end - return result end - else - if errorCount >= 10 then - mod:Toggle(false) - return - end - errorCount = errorCount + 1 - core:print('LUA', L["CustomCommands"], errorMsg) - end + end end function mod:SortArgs(db, commandsString, argsBlockStartIndex) - while sub(commandsString, argsBlockStartIndex, argsBlockStartIndex) == '[' do - local argsBlockEndIndex = find(commandsString, "]", argsBlockStartIndex + 1) - local arguments = sub(commandsString, argsBlockStartIndex + 1, argsBlockEndIndex - 1) - - local _, _, argIndex, negate, argValue = find(arguments, "(%w+)(~?)=([^%]]+)") - - if argValue then - local argIsLua = sub(argValue, 1, 2) == '@@' - - if argIsLua then - argValue = sub(argValue, 3, #argValue) - else - argValue = convertToValue(argValue) - end - - -- store args info - tinsert(db.args, { index = argIndex, argIsLua = argIsLua, arg = argValue, negate = negate == '~' }) - end + while sub(commandsString, argsBlockStartIndex, argsBlockStartIndex) == '[' do + local argsBlockEndIndex = find(commandsString, "]", argsBlockStartIndex + 1) + local arguments = sub(commandsString, argsBlockStartIndex + 1, argsBlockEndIndex - 1) + + local argIndex, negate, argValue = match(arguments, "(%w+)(~?)=([^%]]+)") + + if argValue then + local argIsLua = sub(argValue, 1, 2) == '@@' + local argFunc + + if argIsLua then + argValue = sub(argValue, 3, #argValue) + local luaFunction, errorMsg = loadstring('return '..argValue) + if luaFunction then + local success, fn = pcall(luaFunction) + if not success then + core:print('FAIL', L["CustomCommands"], fn) + argFunc = function() return false end + else + argFunc = luaFunction + end + else + core:print('LUA', L["CustomCommands"], errorMsg) + argFunc = function() return false end + end + else + argValue = convertToValue(argValue) + argFunc = function() return false end + end - argsBlockStartIndex = argsBlockEndIndex + 1 - end + -- Store args info + tinsert(db.args, { index = argIndex, argIsLua = argIsLua, arg = argValue, argFunc = argFunc, negate = negate == '~' }) + end + argsBlockStartIndex = argsBlockEndIndex + 1 + end end function mod:SortEvents(db) - local startIndex = 1 - local eventsString, commandsString = db.events, db.commands - db.args = {} - db.eventCommandsPairs = {} - handler.OnUpdateEvent = false - - while true do - -- check if there are any events - local _, newStartIndex = find(eventsString, "[%u_]+", startIndex) - if not newStartIndex then break end - - local event = sub(eventsString, startIndex, newStartIndex) - event = gsub(event, "%s+", "") - - if upper(event) == 'ONUPDATE' then - handler.OnUpdateEvent = true - else - handler:RegisterEvent(event) - end - - if not db.throttleEvents[event] then - db.throttleEvents[event] = 0.3 - end - - -- check the args - local commandsBlockStart, eventNameEnd = find(commandsString, event, 1, true) - if commandsBlockStart ~= nil then - - -- sort and store args - local argsBlockStartIndex = eventNameEnd + 1 - mod:SortArgs(db, commandsString, argsBlockStartIndex) - - -- locate commands and cut the rest - local _, _, eventCommands = find(commandsString, "@@@(.-)@@@", eventNameEnd) - - -- store values - db.eventCommandsPairs[event] = eventCommands - - end - startIndex = newStartIndex + 1 - end + local eventsString, commandsString = db.events, db.commands + db.args = {} + db.eventCommandsPairs = {} + handler.OnUpdateEvent = false + + for event in gmatch(eventsString, "[%u_]+") do + -- Check the args + local commandsBlockStart, eventNameEnd = find(commandsString, event, 1, true) + if commandsBlockStart ~= nil then + -- Sort and store args + self:SortArgs(db, commandsString, eventNameEnd + 1) + + -- Compile and cache the function + local luaFunction, errorMsg = loadstring("return function(...) "..(match(commandsString, "@@@(.-)@@@", eventNameEnd) or "").." end") + if luaFunction then + local success, fn = pcall(luaFunction) + if not success then + core:print('FAIL', L["CustomCommands"], fn) + fn = function() end + end + db.eventCommandsPairs[event] = fn + if upper(event) == 'ONUPDATE' then + handler.OnUpdateEvent = true + else + handler:RegisterEvent(event) + end + if not db.throttleEvents[event] then + db.throttleEvents[event] = 0.3 + end + else + core:print('LUA', L["CustomCommands"], errorMsg) + db.eventCommandsPairs[event] = function() end + end + end + end end -function mod:CheckArgs(tab, ...) - for _, argTab in ipairs(tab.args) do - local eventArg = select(argTab.index, ...) - if argTab.argIsLua then - -- check the lua arg - local result = mod:LoadCommands('if select(1, ...) == select(2, ...) then return true end', eventArg, argTab.arg) - - if (result and argTab.negate) or (not result and not argTab.negate) then - return true - end - else - if (not argTab.negate and argTab.arg ~= eventArg) - or (argTab.negate and argTab.arg == eventArg) then - return true - end - end - end -end +function mod:SetupHandler(db) + handler:UnregisterAllEvents() -function mod:SetupHandler() - local db = E.db.Extras.general[modName] - handler:UnregisterAllEvents() + local onUpdTabs = {} + local eventTabs = {} - for i = 1, #db.tabs do - if db.tabs[i].enabled and db.tabs[i].commands and db.tabs[i].commands ~= "" and db.tabs[i].events and db.tabs[i].events ~= "" then - mod:SortEvents(db.tabs[i]) - end - end + for _, tab in ipairs(db.tabs) do + if tab.enabled and not tab.preLoad and tab.commands and tab.commands ~= "" and tab.events and tab.events ~= "" then + self:SortEvents(tab) + tinsert(eventTabs, tab) + if find(tab.events, 'ONUPDATE') then + tinsert(onUpdTabs, tab) + end + end + end + + if handler.OnUpdateEvent then + local lastTime = GetTime() + handler:SetScript('OnUpdate', function() + for _, tab in ipairs(onUpdTabs) do + if GetTime() > lastTime + tab.throttleEvents.ONUPDATE then + tab.eventCommandsPairs.ONUPDATE() + lastTime = GetTime() + end + end + end) + end + + handler:SetScript('OnEvent', function(_, event, ...) + for _, tab in ipairs(eventTabs) do + if find(tab.events, event) and (not lastEventTime[event] or (GetTime() >= lastEventTime[event] + (tab.throttleEvents[event] or 0))) then + local failedTheArgs + if ... and #tab.args > 0 then + failedTheArgs = self:CheckArgs(tab, ...) + end + if not failedTheArgs then + tab.eventCommandsPairs[event](...) + lastEventTime[event] = GetTime() + end + end + end + end) +end - if handler.OnUpdateEvent then - local lastTime = GetTime() - handler:SetScript('OnUpdate', function() - for _, tab in pairs(db.tabs) do - if tab.enabled and find(tab.events, 'ONUPDATE') and GetTime() > lastTime + tab.throttleEvents.ONUPDATE then - local commandsToLoad = tab.eventCommandsPairs.ONUPDATE - mod:LoadCommands(commandsToLoad) - lastTime = GetTime() +local data = (E.db.Extras and E.db.Extras.general) and E.db.Extras.general[modName] +if data and data.enabled then + for _, tab in pairs(data.tabs or {}) do + if tab.preLoad and tab.commands then + local luaFunction, errorMsg = loadstring("return function(...) "..tab.commands.." end") + if luaFunction then + local luaFunction, fn = pcall(luaFunction) + if not luaFunction then + print(L["CustomCommands"], fn) + return end - end - end) - end - handler:SetScript('OnEvent', function(self, event, ...) - for _, tab in pairs(db.tabs) do - if tab.enabled and find(tab.events, event) and (not lastEventTime or (GetTime() > lastEventTime + (tab.throttleEvents[event] or 0))) then - local commandsToLoad = tab.eventCommandsPairs[event] - local failedTheArgs - if ... and #tab.args > 0 then - failedTheArgs = mod:CheckArgs(tab, ...) - end - if not failedTheArgs then - mod:LoadCommands(commandsToLoad, nil, nil, ...) - lastEventTime = GetTime() + local success, result = pcall(fn, ...) + if not success then + print(L["CustomCommands"], result) end + else + print(L["CustomCommands"], errorMsg) end end - end) + end end -function mod:Toggle(enable) - if enable then - self:SetupHandler() +function mod:Toggle(db) + if not core.reload and db and db.enabled then + self:SetupHandler(db) initialized = true elseif initialized then handler:UnregisterAllEvents() handler:SetScript("OnUpdate", nil) handler:UnregisterAllEvents("OnEvent", nil) - if errorCount >= 10 then - print(format(core.customColorAlpha.."ElvUI "..core.pluginColor.."Extras "..core.customColorAlpha..","..core.customColorBeta.." %s "..core.customColorBad..' '..INTERRUPTED, L["CustomCommands"])) - for _, tab in pairs(E.db.Extras.general[modName].tabs) do - tab.enabled = false - end - end - errorCount = 0 end end function mod:InitializeCallback() mod:LoadConfig() - mod:Toggle(E.db.Extras.general[modName].enabled) + mod:Toggle(E.db.Extras.general[modName]) end core.modules[modName] = mod.InitializeCallback \ No newline at end of file diff --git a/Modules/General/Misc.lua b/Modules/General/Misc.lua index 7e7ea84..6420a6e 100644 --- a/Modules/General/Misc.lua +++ b/Modules/General/Misc.lua @@ -15,7 +15,7 @@ local GetSpellLink, GetSpellTexture = GetSpellLink, GetSpellTexture local UnitExists, GetItemIcon = UnitExists, GetItemIcon local ITEM_SPELL_TRIGGER_ONEQUIP = "^"..ITEM_SPELL_TRIGGER_ONEQUIP local ITEM_SPELL_TRIGGER_ONUSE = "^"..ITEM_SPELL_TRIGGER_ONUSE -local ITEM_COOLDOWN_TOTAL = format(gsub(ITEM_COOLDOWN_TOTAL, "[%(%)]", ""), SECONDS_ABBR) +local ITEM_COOLDOWN_TOTAL = format(gsub(ITEM_COOLDOWN_TOTAL, "[%(%)]", ""), gsub(SECONDS_ABBR, "%.$", "")) local ITEM_SET_BONUS = gsub(format(ITEM_SET_BONUS, 1), "[1%p]+", "") local procStats = core.Misc_data and core.Misc_data[GetLocale()] or {} @@ -77,25 +77,25 @@ P["Extras"]["general"][modName] = { ["TooltipNotes"] = { ["enabled"] = false, ["desc"] = L["Usage:".. - "\n/tnote list - returns all eixting notes".. - "\n/tnote wipe - clears all existing notes".. - "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. - "\n/tnote 1 get - same as set, returns existing notes".. - "\n/tnote 1 set YourNoteHere - adds a note to the designated index from the list ".. - "or to a currently shown tooltip text if the second argument (1 in this case) is ommitted, ".. - "supports functions and coloring ".. - "(providing no text clears the note);".. - "\nto break the lines, use ::".. - "\n\nExample:".. - "\n\n/tnote 3 set fire pre-bis::source: Joseph Mama".. - "\n\n/tnote set local percentage =".. - "\n UnitHealth('mouseover') / ".. - "\n UnitHealthMax('mouseover')".. - "\nreturn string.format('\124\124cffffd100(default color)'".. - "\n ..UnitName('mouseover')".. - "\n ..': \124\124cff%02x%02x00'".. - "\n ..UnitHealth('mouseover'), ".. - "\n (1-percentage)*255, percentage*255)"], + "\n/tnote list - returns all existing notes".. + "\n/tnote wipe - clears all existing notes".. + "\n/tnote 1 icon Interface\\Path\\ToYourIcon - same as set (except for the lua part)".. + "\n/tnote 1 get - same as set, returns existing notes".. + "\n/tnote 1 set YourNoteHere - adds a note to the designated index from the list ".. + "or to a currently shown tooltip text if the second argument (1 in this case) is ommitted, ".. + "supports functions and coloring ".. + "(providing no text clears the note);".. + "\nto break the lines, use ::".. + "\n\nExample:".. + "\n\n/tnote 3 set fire pre-bis::source: Joseph Mama".. + "\n\n/tnote set local percentage =".. + "\n UnitHealth('mouseover') / ".. + "\n UnitHealthMax('mouseover')".. + "\nreturn string.format('\124\124cffffd100(default color)'".. + "\n ..UnitName('mouseover')".. + "\n ..': \124\124cff%02x%02x00'".. + "\n ..UnitHealth('mouseover'), ".. + "\n (1-percentage)*255, percentage*255)"], ["notes"] = {}, }, ["EnterCombatAlert"] = { @@ -362,7 +362,6 @@ function mod:InternalCooldowns(enable) end end - function mod:TooltipNotes(enable) if enable then local notes = E.db.Extras.general[modName].TooltipNotes.notes @@ -744,9 +743,9 @@ function mod:ItemIcons(enable) local numMessages = frame:GetNumMessages() local ChatTypeInfo = ChatTypeInfo - for i = max(1, numMessages - maxLines + 1), numMessages do - if numMessages - i > maxLines then break end - local msg, _, lineID = frame:GetMessageInfo(i) + for j = max(1, numMessages - maxLines + 1), numMessages do + if numMessages - j > maxLines then break end + local msg, _, lineID = frame:GetMessageInfo(j) local info = ChatTypeInfo[chatTypeIndexToName[lineID]] local r, g, b = info.r, info.g, info.b tinsert(messages[frame], {msg = msg, r = r, g = g, b = b}) @@ -840,10 +839,11 @@ function mod:GlobalShadow(enable) end end + function mod:Toggle() - for mod, info in pairs(E.db.Extras.general[modName]) do - if self[mod] and info.enabled ~= nil then - self[mod](self, info.enabled) + for subMod, info in pairs(E.db.Extras.general[modName]) do + if self[subMod] and info.enabled ~= nil then + self[subMod](self, core.reload and false or info.enabled) end end end diff --git a/Modules/General/Misc_data.lua b/Modules/General/Misc_data.lua index 163b98d..66c9778 100644 --- a/Modules/General/Misc_data.lua +++ b/Modules/General/Misc_data.lua @@ -1,6048 +1,6048 @@ ElvUI[1]:GetModule("Extras").Misc_data = { ["enUS"] = { ["1490"] = { -- Guardian Talisman - text = "(Proc chance: 2%%)", + text = "(Proc chance: 2%%.)", cooldown = 0, pos = 1, }, ["11302"] = { -- Uther's Strength - text = "(Proc chance: 2%%)", + text = "(Proc chance: 2%%.)", cooldown = 0, pos = 1, }, ["11810"] = { -- Force of Will - text = "(Proc chance: 1%%)", + text = "(Proc chance: 1%%.)", cooldown = 0, pos = 1, }, ["11815"] = { -- Hand of Justice - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["14557"] = { -- The Lion Horn of Stormwind - text = "(Proc chance: 1%%)", + text = "(Proc chance: 1%%.)", cooldown = 0, pos = 1, }, ["17774"] = { -- Mark of the Chosen - text = "(Proc chance: 2%%)", + text = "(Proc chance: 2%%.)", cooldown = 0, pos = 1, }, ["19288"] = { -- Darkmoon Card: Blue Dragon - text = "(Proc chance: 2%%)", + text = "(Proc chance: 2%%.)", cooldown = 0, pos = 1, }, ["27683"] = { -- Quagmirran's Eye - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["27896"] = { -- Alembic of Infernal Power - text = "(Proc chance: 2%%)", + text = "(Proc chance: 2%%.)", cooldown = 0, pos = 2, }, ["27922"] = { -- Mark of Defiance - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27924"] = { -- Mark of Defiance - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27926"] = { -- Mark of Vindication - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 25, pos = 2, }, ["27927"] = { -- Mark of Vindication - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 25, pos = 2, }, ["28034"] = { -- Hourglass of the Unraveller - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["28108"] = { -- Power Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28109"] = { -- Essence Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28190"] = { -- Scarab of the Infinite Cycle - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["28418"] = { -- Shiffar's Nexus-Horn - text = "(Proc chance: 20%%, %s)", + text = "(Proc chance: 20%%. %s.)", cooldown = 45, pos = 2, }, ["28785"] = { -- The Lightning Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["28823"] = { -- Eye of Gruul - text = "(Proc chance: 2%%)", + text = "(Proc chance: 2%%.)", cooldown = 0, pos = 2, }, ["28830"] = { -- Dragonspine Trophy - text = "(%s)", + text = "(%s.)", cooldown = 20, pos = 2, }, ["30447"] = { -- Tome of Fiery Redemption - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 1, }, ["30450"] = { -- Warp-Spring Coil - text = "(Proc chance: 25%%, %s)", + text = "(Proc chance: 25%%. %s.)", cooldown = 30, pos = 2, }, ["30619"] = { -- Fel Reaver's Piston - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 15, pos = 1, }, ["30626"] = { -- Sextant of Unstable Currents - text = "(Proc chance: 20%%, %s)", + text = "(Proc chance: 20%%. %s.)", cooldown = 45, pos = 2, }, ["30627"] = { -- Tsunami Talisman - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 3, }, ["30663"] = { -- Fathom-Brooch of the Tidewalker - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 40, pos = 1, }, ["30664"] = { -- Living Root of the Wildheart - text = "(Proc chance: 3%%)", + text = "(Proc chance: 3%%.)", cooldown = 0, pos = 1, }, ["31858"] = { -- Darkmoon Card: Vengeance - text = "(Proc chance: 10%%)", + text = "(Proc chance: 10%%.)", cooldown = 0, pos = 1, }, ["32485"] = { -- Ashtongue Talisman of Valor - text = "(Proc chance: 25%%)", + text = "(Proc chance: 25%%.)", cooldown = 0, pos = 1, }, ["32487"] = { -- Ashtongue Talisman of Swiftness - text = "(Proc chance: 15%%)", + text = "(Proc chance: 15%%.)", cooldown = 0, pos = 1, }, ["32488"] = { -- Ashtongue Talisman of Insight - text = "(Proc chance: 50%%)", + text = "(Proc chance: 50%%.)", cooldown = 0, pos = 1, }, ["32490"] = { -- Ashtongue Talisman of Acumen - text = "(Proc chance: 10%%)", + text = "(Proc chance: 10%%.)", cooldown = 0, pos = 1, }, ["32493"] = { -- Ashtongue Talisman of Shadows - text = "(Proc chance: 20%%)", + text = "(Proc chance: 20%%.)", cooldown = 0, pos = 1, }, ["32496"] = { -- Memento of Tyrande - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["32770"] = { -- Skyguard Silver Cross - text = "(Proc chance: 50%%, %s)", + text = "(Proc chance: 50%%. %s.)", cooldown = 10, pos = 2, }, ["32771"] = { -- Airman's Ribbon of Gallantry - text = "(Proc chance: 50%%, %s)", + text = "(Proc chance: 50%%. %s.)", cooldown = 10, pos = 2, }, ["34427"] = { -- Blackened Naaru Sliver - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34470"] = { -- Timbal's Focusing Crystal - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 15, pos = 1, }, ["34472"] = { -- Shard of Contempt - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34473"] = { -- Commendation of Kael'thas - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 1, }, ["37064"] = { -- Vestige of Haldor - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37111"] = { -- Soul Preserver - text = "(Proc chance: 2%%)", + text = "(Proc chance: 2%%.)", cooldown = 0, pos = 2, }, ["37220"] = { -- Essence of Gossamer - text = "(Proc chance: 5%%, %s)", + text = "(Proc chance: 5%%. %s.)", cooldown = 50, pos = 1, }, ["37264"] = { -- Pendulum of Telluric Currents - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37390"] = { -- Meteorite Whetstone - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37559"] = { -- Serrah's Star - text = "(Proc chance: 45%%, %s)", + text = "(Proc chance: 45%%. %s.)", cooldown = 45, pos = 2, }, ["37657"] = { -- Spark of Life - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["37660"] = { -- Forge Ember - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["37835"] = { -- Je'Tze's Bell - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 1, }, ["38071"] = { -- Valonforth's Remembrance - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["38072"] = { -- Thunder Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["38212"] = { -- Death Knight's Anguish - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["38358"] = { -- Arcane Revitalizer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38359"] = { -- Goblin Repetition Reducer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38674"] = { -- Soul Harvester's Charm - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["38675"] = { -- Signet of the Dark Brotherhood - text = "(Proc chance: 30%%, %s)", + text = "(Proc chance: 30%%. %s.)", cooldown = 45, pos = 2, }, ["39229"] = { -- Embrace of the Spider - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["39889"] = { -- Horn of Argent Fury - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 1, }, ["40255"] = { -- Dying Curse - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40256"] = { -- Grim Toll - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40258"] = { -- Forethought Talisman - text = "(Proc chance: 20%%, %s)", + text = "(Proc chance: 20%%. %s.)", cooldown = 45, pos = 2, }, ["40371"] = { -- Bandit's Insignia - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40373"] = { -- Extract of Necromantic Power - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 15, pos = 2, }, ["40382"] = { -- Soul of the Dead - text = "(Proc chance: 25%%, %s)", + text = "(Proc chance: 25%%. %s.)", cooldown = 45, pos = 2, }, ["40682"] = { -- Sundial of the Exiled - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40684"] = { -- Mirror of Truth - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["40685"] = { -- The Egg of Mortal Essence - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40767"] = { -- Sonic Booster - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 50, pos = 1, }, ["40865"] = { -- Noise Machine - text = "(Proc chance: 50%%, %s)", + text = "(Proc chance: 50%%. %s.)", cooldown = 50, pos = 2, }, ["42987"] = { -- Darkmoon Card: Greatness - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 1, }, ["42989"] = { -- Darkmoon Card: Berserker! - text = "(Proc chance: 50%%)", + text = "(Proc chance: 50%%.)", cooldown = 0, pos = 2, }, ["42990"] = { -- Darkmoon Card: Death - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43573"] = { -- Tears of Bitter Anguish - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["43829"] = { -- Crusader's Locket - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43838"] = { -- Chuchu's Tiny Box of Horrors - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["44253"] = { -- Darkmoon Card: Greatness - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44254"] = { -- Darkmoon Card: Greatness - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44255"] = { -- Darkmoon Card: Greatness - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44912"] = { -- Flow of Knowledge - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["44914"] = { -- Anvil of Titans - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45131"] = { -- Jouster's Fury - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45286"] = { -- Pyrite Infuser - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45490"] = { -- Pandora's Plea - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 1, }, ["45507"] = { -- The General's Heart - text = "(Proc chance: 5%%, %s)", + text = "(Proc chance: 5%%. %s.)", cooldown = 50, pos = 2, }, ["45518"] = { -- Flare of the Heavens - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45522"] = { -- Blood of the Old God - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45535"] = { -- Show of Faith - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45609"] = { -- Comet's Trail - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["45866"] = { -- Elemental Focus Stone - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45929"] = { -- Sif's Remembrance - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45931"] = { -- Mjolnir Runestone - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["46038"] = { -- Dark Matter - text = "(Proc chance: 15%%, %s)", + text = "(Proc chance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["47115"] = { -- Death's Verdict - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47131"] = { -- Death's Verdict - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47182"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47188"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47213"] = { -- Abyssal Rune - text = "(Proc chance: 25%%, %s)", + text = "(Proc chance: 25%%. %s.)", cooldown = 45, pos = 2, }, ["47214"] = { -- Banner of Victory - text = "(Proc chance: 20%%, %s)", + text = "(Proc chance: 20%%. %s.)", cooldown = 50, pos = 2, }, ["47215"] = { -- Tears of the Vanquished - text = "(Proc chance: 25%%, %s)", + text = "(Proc chance: 25%%. %s.)", cooldown = 45, pos = 1, }, ["47216"] = { -- The Black Heart - text = "(Proc chance: 25%%, %s)", + text = "(Proc chance: 25%%. %s.)", cooldown = 50, pos = 1, }, ["47303"] = { -- Death's Choice - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47316"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47464"] = { -- Death's Choice - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47477"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["49074"] = { -- Coren's Chromium Coaster - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["49076"] = { -- Mithril Pocketwatch - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49078"] = { -- Ancient Pickled Egg - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49310"] = { -- Purified Shard of the Scale - text = "(Proc chance: 25%%, %s)", + text = "(Proc chance: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49463"] = { -- Purified Shard of the Flame - text = "(Proc chance: 25%%, %s)", + text = "(Proc chance: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49464"] = { -- Shiny Shard of the Flame - text = "(Proc chance: 25%%, %s)", + text = "(Proc chance: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49488"] = { -- Shiny Shard of the Scale - text = "(Proc chance: 25%%, %s)", + text = "(Proc chance: 25%%. %s.)", cooldown = 50, pos = 3, }, ["50198"] = { -- Needle-Encrusted Scorpion - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50341"] = { -- Unidentifiable Organ - text = "(Proc chance: 60%%)", + text = "(Proc chance: 60%%.)", cooldown = 0, pos = 1, }, ["50342"] = { -- Whispering Fanged Skull - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50343"] = { -- Whispering Fanged Skull - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50344"] = { -- Unidentifiable Organ - text = "(Proc chance: 60%%)", + text = "(Proc chance: 60%%.)", cooldown = 0, pos = 1, }, ["50348"] = { -- Dislodged Foreign Object - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50349"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50352"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50353"] = { -- Dislodged Foreign Object - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50358"] = { -- Purified Lunar Dust - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50359"] = { -- Althor's Abacus - text = "(Proc chance: 30%%, %s)", + text = "(Proc chance: 30%%. %s.)", cooldown = 45, pos = 2, }, ["50360"] = { -- Phylactery of the Nameless Lich - text = "(Proc chance: 30%%, %s)", + text = "(Proc chance: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50362"] = { -- Deathbringer's Will - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50363"] = { -- Deathbringer's Will - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50365"] = { -- Phylactery of the Nameless Lich - text = "(Proc chance: 30%%, %s)", + text = "(Proc chance: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50366"] = { -- Althor's Abacus - text = "(Proc chance: 30%%, %s)", + text = "(Proc chance: 30%%. %s.)", cooldown = 45, pos = 2, }, ["54569"] = { -- Sharpened Twilight Scale - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54571"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, ["54572"] = { -- Charred Twilight Scale - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54588"] = { -- Charred Twilight Scale - text = "(Proc chance: 10%%, %s)", + text = "(Proc chance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54590"] = { -- Sharpened Twilight Scale - text = "(Proc chance: 35%%, %s)", + text = "(Proc chance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54591"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, }, ["deDE"] = { ["1490"] = { -- Guardian Talisman - text = "(Procchance: 2%%)", + text = "(Procchance: 2%%.)", cooldown = 0, pos = 1, }, ["11302"] = { -- Uther's Strength - text = "(Procchance: 2%%)", + text = "(Procchance: 2%%.)", cooldown = 0, pos = 1, }, ["11810"] = { -- Force of Will - text = "(Procchance: 1%%)", + text = "(Procchance: 1%%.)", cooldown = 0, pos = 1, }, ["11815"] = { -- Hand of Justice - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["14557"] = { -- The Lion Horn of Stormwind - text = "(Procchance: 1%%)", + text = "(Procchance: 1%%.)", cooldown = 0, pos = 1, }, ["17774"] = { -- Mark of the Chosen - text = "(Procchance: 2%%)", + text = "(Procchance: 2%%.)", cooldown = 0, pos = 1, }, ["19288"] = { -- Darkmoon Card: Blue Dragon - text = "(Procchance: 2%%)", + text = "(Procchance: 2%%.)", cooldown = 0, pos = 1, }, ["27683"] = { -- Quagmirran's Eye - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["27896"] = { -- Alembic of Infernal Power - text = "(Procchance: 2%%)", + text = "(Procchance: 2%%.)", cooldown = 0, pos = 2, }, ["27922"] = { -- Mark of Defiance - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27924"] = { -- Mark of Defiance - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27926"] = { -- Mark of Vindication - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 25, pos = 2, }, ["27927"] = { -- Mark of Vindication - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 25, pos = 2, }, ["28034"] = { -- Hourglass of the Unraveller - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["28108"] = { -- Power Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28109"] = { -- Essence Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28190"] = { -- Scarab of the Infinite Cycle - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["28418"] = { -- Shiffar's Nexus-Horn - text = "(Procchance: 20%%, %s)", + text = "(Procchance: 20%%. %s.)", cooldown = 45, pos = 2, }, ["28785"] = { -- The Lightning Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["28823"] = { -- Eye of Gruul - text = "(Procchance: 2%%)", + text = "(Procchance: 2%%.)", cooldown = 0, pos = 2, }, ["28830"] = { -- Dragonspine Trophy - text = "(%s)", + text = "(%s.)", cooldown = 20, pos = 2, }, ["30447"] = { -- Tome of Fiery Redemption - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 1, }, ["30450"] = { -- Warp-Spring Coil - text = "(Procchance: 25%%, %s)", + text = "(Procchance: 25%%. %s.)", cooldown = 30, pos = 2, }, ["30619"] = { -- Fel Reaver's Piston - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 15, pos = 1, }, ["30626"] = { -- Sextant of Unstable Currents - text = "(Procchance: 20%%, %s)", + text = "(Procchance: 20%%. %s.)", cooldown = 45, pos = 2, }, ["30627"] = { -- Tsunami Talisman - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 3, }, ["30663"] = { -- Fathom-Brooch of the Tidewalker - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 40, pos = 1, }, ["30664"] = { -- Living Root of the Wildheart - text = "(Procchance: 3%%)", + text = "(Procchance: 3%%.)", cooldown = 0, pos = 1, }, ["31858"] = { -- Darkmoon Card: Vengeance - text = "(Procchance: 10%%)", + text = "(Procchance: 10%%.)", cooldown = 0, pos = 1, }, ["32485"] = { -- Ashtongue Talisman of Valor - text = "(Procchance: 25%%)", + text = "(Procchance: 25%%.)", cooldown = 0, pos = 1, }, ["32487"] = { -- Ashtongue Talisman of Swiftness - text = "(Procchance: 15%%)", + text = "(Procchance: 15%%.)", cooldown = 0, pos = 1, }, ["32488"] = { -- Ashtongue Talisman of Insight - text = "(Procchance: 50%%)", + text = "(Procchance: 50%%.)", cooldown = 0, pos = 1, }, ["32490"] = { -- Ashtongue Talisman of Acumen - text = "(Procchance: 10%%)", + text = "(Procchance: 10%%.)", cooldown = 0, pos = 1, }, ["32493"] = { -- Ashtongue Talisman of Shadows - text = "(Procchance: 20%%)", + text = "(Procchance: 20%%.)", cooldown = 0, pos = 1, }, ["32496"] = { -- Memento of Tyrande - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["32770"] = { -- Skyguard Silver Cross - text = "(Procchance: 50%%, %s)", + text = "(Procchance: 50%%. %s.)", cooldown = 10, pos = 2, }, ["32771"] = { -- Airman's Ribbon of Gallantry - text = "(Procchance: 50%%, %s)", + text = "(Procchance: 50%%. %s.)", cooldown = 10, pos = 2, }, ["34427"] = { -- Blackened Naaru Sliver - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34470"] = { -- Timbal's Focusing Crystal - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 15, pos = 1, }, ["34472"] = { -- Shard of Contempt - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34473"] = { -- Commendation of Kael'thas - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 1, }, ["37064"] = { -- Vestige of Haldor - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37111"] = { -- Soul Preserver - text = "(Procchance: 2%%)", + text = "(Procchance: 2%%.)", cooldown = 0, pos = 2, }, ["37220"] = { -- Essence of Gossamer - text = "(Procchance: 5%%, %s)", + text = "(Procchance: 5%%. %s.)", cooldown = 50, pos = 1, }, ["37264"] = { -- Pendulum of Telluric Currents - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37390"] = { -- Meteorite Whetstone - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37559"] = { -- Serrah's Star - text = "(Procchance: 45%%, %s)", + text = "(Procchance: 45%%. %s.)", cooldown = 45, pos = 2, }, ["37657"] = { -- Spark of Life - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["37660"] = { -- Forge Ember - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["37835"] = { -- Je'Tze's Bell - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 1, }, ["38071"] = { -- Valonforth's Remembrance - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["38072"] = { -- Thunder Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["38212"] = { -- Death Knight's Anguish - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["38358"] = { -- Arcane Revitalizer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38359"] = { -- Goblin Repetition Reducer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38674"] = { -- Soul Harvester's Charm - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["38675"] = { -- Signet of the Dark Brotherhood - text = "(Procchance: 30%%, %s)", + text = "(Procchance: 30%%. %s.)", cooldown = 45, pos = 2, }, ["39229"] = { -- Embrace of the Spider - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["39889"] = { -- Horn of Argent Fury - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 1, }, ["40255"] = { -- Dying Curse - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40256"] = { -- Grim Toll - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40258"] = { -- Forethought Talisman - text = "(Procchance: 20%%, %s)", + text = "(Procchance: 20%%. %s.)", cooldown = 45, pos = 2, }, ["40371"] = { -- Bandit's Insignia - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40373"] = { -- Extract of Necromantic Power - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 15, pos = 2, }, ["40382"] = { -- Soul of the Dead - text = "(Procchance: 25%%, %s)", + text = "(Procchance: 25%%. %s.)", cooldown = 45, pos = 2, }, ["40682"] = { -- Sundial of the Exiled - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40684"] = { -- Mirror of Truth - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["40685"] = { -- The Egg of Mortal Essence - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40767"] = { -- Sonic Booster - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 50, pos = 1, }, ["40865"] = { -- Noise Machine - text = "(Procchance: 50%%, %s)", + text = "(Procchance: 50%%. %s.)", cooldown = 50, pos = 2, }, ["42987"] = { -- Darkmoon Card: Greatness - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 1, }, ["42989"] = { -- Darkmoon Card: Berserker! - text = "(Procchance: 50%%)", + text = "(Procchance: 50%%.)", cooldown = 0, pos = 2, }, ["42990"] = { -- Darkmoon Card: Death - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43573"] = { -- Tears of Bitter Anguish - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["43829"] = { -- Crusader's Locket - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43838"] = { -- Chuchu's Tiny Box of Horrors - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["44253"] = { -- Darkmoon Card: Greatness - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44254"] = { -- Darkmoon Card: Greatness - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44255"] = { -- Darkmoon Card: Greatness - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44912"] = { -- Flow of Knowledge - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["44914"] = { -- Anvil of Titans - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45131"] = { -- Jouster's Fury - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45286"] = { -- Pyrite Infuser - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45490"] = { -- Pandora's Plea - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 1, }, ["45507"] = { -- The General's Heart - text = "(Procchance: 5%%, %s)", + text = "(Procchance: 5%%. %s.)", cooldown = 50, pos = 2, }, ["45518"] = { -- Flare of the Heavens - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45522"] = { -- Blood of the Old God - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45535"] = { -- Show of Faith - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45609"] = { -- Comet's Trail - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["45866"] = { -- Elemental Focus Stone - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45929"] = { -- Sif's Remembrance - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45931"] = { -- Mjolnir Runestone - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["46038"] = { -- Dark Matter - text = "(Procchance: 15%%, %s)", + text = "(Procchance: 15%%. %s.)", cooldown = 45, pos = 2, }, ["47115"] = { -- Death's Verdict - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47131"] = { -- Death's Verdict - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47182"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47188"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47213"] = { -- Abyssal Rune - text = "(Procchance: 25%%, %s)", + text = "(Procchance: 25%%. %s.)", cooldown = 45, pos = 2, }, ["47214"] = { -- Banner of Victory - text = "(Procchance: 20%%, %s)", + text = "(Procchance: 20%%. %s.)", cooldown = 50, pos = 2, }, ["47215"] = { -- Tears of the Vanquished - text = "(Procchance: 25%%, %s)", + text = "(Procchance: 25%%. %s.)", cooldown = 45, pos = 1, }, ["47216"] = { -- The Black Heart - text = "(Procchance: 25%%, %s)", + text = "(Procchance: 25%%. %s.)", cooldown = 50, pos = 1, }, ["47303"] = { -- Death's Choice - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47316"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47464"] = { -- Death's Choice - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47477"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["49074"] = { -- Coren's Chromium Coaster - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["49076"] = { -- Mithril Pocketwatch - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49078"] = { -- Ancient Pickled Egg - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49310"] = { -- Purified Shard of the Scale - text = "(Procchance: 25%%, %s)", + text = "(Procchance: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49463"] = { -- Purified Shard of the Flame - text = "(Procchance: 25%%, %s)", + text = "(Procchance: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49464"] = { -- Shiny Shard of the Flame - text = "(Procchance: 25%%, %s)", + text = "(Procchance: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49488"] = { -- Shiny Shard of the Scale - text = "(Procchance: 25%%, %s)", + text = "(Procchance: 25%%. %s.)", cooldown = 50, pos = 3, }, ["50198"] = { -- Needle-Encrusted Scorpion - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50341"] = { -- Unidentifiable Organ - text = "(Procchance: 60%%)", + text = "(Procchance: 60%%.)", cooldown = 0, pos = 1, }, ["50342"] = { -- Whispering Fanged Skull - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50343"] = { -- Whispering Fanged Skull - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50344"] = { -- Unidentifiable Organ - text = "(Procchance: 60%%)", + text = "(Procchance: 60%%.)", cooldown = 0, pos = 1, }, ["50348"] = { -- Dislodged Foreign Object - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50349"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50352"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50353"] = { -- Dislodged Foreign Object - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50358"] = { -- Purified Lunar Dust - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50359"] = { -- Althor's Abacus - text = "(Procchance: 30%%, %s)", + text = "(Procchance: 30%%. %s.)", cooldown = 45, pos = 2, }, ["50360"] = { -- Phylactery of the Nameless Lich - text = "(Procchance: 30%%, %s)", + text = "(Procchance: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50362"] = { -- Deathbringer's Will - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50363"] = { -- Deathbringer's Will - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50365"] = { -- Phylactery of the Nameless Lich - text = "(Procchance: 30%%, %s)", + text = "(Procchance: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50366"] = { -- Althor's Abacus - text = "(Procchance: 30%%, %s)", + text = "(Procchance: 30%%. %s.)", cooldown = 45, pos = 2, }, ["54569"] = { -- Sharpened Twilight Scale - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54571"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, ["54572"] = { -- Charred Twilight Scale - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54588"] = { -- Charred Twilight Scale - text = "(Procchance: 10%%, %s)", + text = "(Procchance: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54590"] = { -- Sharpened Twilight Scale - text = "(Procchance: 35%%, %s)", + text = "(Procchance: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54591"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, }, ["esMX"] = { ["1490"] = { -- Guardian Talisman - text = "(Probabilidad de que accione: 2%%)", + text = "(Probabilidad de que accione: 2%%.)", cooldown = 0, pos = 1, }, ["11302"] = { -- Uther's Strength - text = "(Probabilidad de que accione: 2%%)", + text = "(Probabilidad de que accione: 2%%.)", cooldown = 0, pos = 1, }, ["11810"] = { -- Force of Will - text = "(Probabilidad de que accione: 1%%)", + text = "(Probabilidad de que accione: 1%%.)", cooldown = 0, pos = 1, }, ["11815"] = { -- Hand of Justice - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["14557"] = { -- The Lion Horn of Stormwind - text = "(Probabilidad de que accione: 1%%)", + text = "(Probabilidad de que accione: 1%%.)", cooldown = 0, pos = 1, }, ["17774"] = { -- Mark of the Chosen - text = "(Probabilidad de que accione: 2%%)", + text = "(Probabilidad de que accione: 2%%.)", cooldown = 0, pos = 1, }, ["19288"] = { -- Darkmoon Card: Blue Dragon - text = "(Probabilidad de que accione: 2%%)", + text = "(Probabilidad de que accione: 2%%.)", cooldown = 0, pos = 1, }, ["27683"] = { -- Quagmirran's Eye - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["27896"] = { -- Alembic of Infernal Power - text = "(Probabilidad de que accione: 2%%)", + text = "(Probabilidad de que accione: 2%%.)", cooldown = 0, pos = 2, }, ["27922"] = { -- Mark of Defiance - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27924"] = { -- Mark of Defiance - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27926"] = { -- Mark of Vindication - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 25, pos = 2, }, ["27927"] = { -- Mark of Vindication - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 25, pos = 2, }, ["28034"] = { -- Hourglass of the Unraveller - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["28108"] = { -- Power Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28109"] = { -- Essence Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28190"] = { -- Scarab of the Infinite Cycle - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["28418"] = { -- Shiffar's Nexus-Horn - text = "(Probabilidad de que accione: 20%%, %s)", + text = "(Probabilidad de que accione: 20%%. %s.)", cooldown = 45, pos = 2, }, ["28785"] = { -- The Lightning Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["28823"] = { -- Eye of Gruul - text = "(Probabilidad de que accione: 2%%)", + text = "(Probabilidad de que accione: 2%%.)", cooldown = 0, pos = 2, }, ["28830"] = { -- Dragonspine Trophy - text = "(%s)", + text = "(%s.)", cooldown = 20, pos = 2, }, ["30447"] = { -- Tome of Fiery Redemption - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 1, }, ["30450"] = { -- Warp-Spring Coil - text = "(Probabilidad de que accione: 25%%, %s)", + text = "(Probabilidad de que accione: 25%%. %s.)", cooldown = 30, pos = 2, }, ["30619"] = { -- Fel Reaver's Piston - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 15, pos = 1, }, ["30626"] = { -- Sextant of Unstable Currents - text = "(Probabilidad de que accione: 20%%, %s)", + text = "(Probabilidad de que accione: 20%%. %s.)", cooldown = 45, pos = 2, }, ["30627"] = { -- Tsunami Talisman - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 3, }, ["30663"] = { -- Fathom-Brooch of the Tidewalker - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 40, pos = 1, }, ["30664"] = { -- Living Root of the Wildheart - text = "(Probabilidad de que accione: 3%%)", + text = "(Probabilidad de que accione: 3%%.)", cooldown = 0, pos = 1, }, ["31858"] = { -- Darkmoon Card: Vengeance - text = "(Probabilidad de que accione: 10%%)", + text = "(Probabilidad de que accione: 10%%.)", cooldown = 0, pos = 1, }, ["32485"] = { -- Ashtongue Talisman of Valor - text = "(Probabilidad de que accione: 25%%)", + text = "(Probabilidad de que accione: 25%%.)", cooldown = 0, pos = 1, }, ["32487"] = { -- Ashtongue Talisman of Swiftness - text = "(Probabilidad de que accione: 15%%)", + text = "(Probabilidad de que accione: 15%%.)", cooldown = 0, pos = 1, }, ["32488"] = { -- Ashtongue Talisman of Insight - text = "(Probabilidad de que accione: 50%%)", + text = "(Probabilidad de que accione: 50%%.)", cooldown = 0, pos = 1, }, ["32490"] = { -- Ashtongue Talisman of Acumen - text = "(Probabilidad de que accione: 10%%)", + text = "(Probabilidad de que accione: 10%%.)", cooldown = 0, pos = 1, }, ["32493"] = { -- Ashtongue Talisman of Shadows - text = "(Probabilidad de que accione: 20%%)", + text = "(Probabilidad de que accione: 20%%.)", cooldown = 0, pos = 1, }, ["32496"] = { -- Memento of Tyrande - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["32770"] = { -- Skyguard Silver Cross - text = "(Probabilidad de que accione: 50%%, %s)", + text = "(Probabilidad de que accione: 50%%. %s.)", cooldown = 10, pos = 2, }, ["32771"] = { -- Airman's Ribbon of Gallantry - text = "(Probabilidad de que accione: 50%%, %s)", + text = "(Probabilidad de que accione: 50%%. %s.)", cooldown = 10, pos = 2, }, ["34427"] = { -- Blackened Naaru Sliver - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34470"] = { -- Timbal's Focusing Crystal - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 15, pos = 1, }, ["34472"] = { -- Shard of Contempt - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34473"] = { -- Commendation of Kael'thas - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 1, }, ["37064"] = { -- Vestige of Haldor - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37111"] = { -- Soul Preserver - text = "(Probabilidad de que accione: 2%%)", + text = "(Probabilidad de que accione: 2%%.)", cooldown = 0, pos = 2, }, ["37220"] = { -- Essence of Gossamer - text = "(Probabilidad de que accione: 5%%, %s)", + text = "(Probabilidad de que accione: 5%%. %s.)", cooldown = 50, pos = 1, }, ["37264"] = { -- Pendulum of Telluric Currents - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37390"] = { -- Meteorite Whetstone - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37559"] = { -- Serrah's Star - text = "(Probabilidad de que accione: 45%%, %s)", + text = "(Probabilidad de que accione: 45%%. %s.)", cooldown = 45, pos = 2, }, ["37657"] = { -- Spark of Life - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["37660"] = { -- Forge Ember - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["37835"] = { -- Je'Tze's Bell - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 1, }, ["38071"] = { -- Valonforth's Remembrance - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["38072"] = { -- Thunder Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["38212"] = { -- Death Knight's Anguish - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["38358"] = { -- Arcane Revitalizer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38359"] = { -- Goblin Repetition Reducer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38674"] = { -- Soul Harvester's Charm - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["38675"] = { -- Signet of the Dark Brotherhood - text = "(Probabilidad de que accione: 30%%, %s)", + text = "(Probabilidad de que accione: 30%%. %s.)", cooldown = 45, pos = 2, }, ["39229"] = { -- Embrace of the Spider - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["39889"] = { -- Horn of Argent Fury - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 1, }, ["40255"] = { -- Dying Curse - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40256"] = { -- Grim Toll - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40258"] = { -- Forethought Talisman - text = "(Probabilidad de que accione: 20%%, %s)", + text = "(Probabilidad de que accione: 20%%. %s.)", cooldown = 45, pos = 2, }, ["40371"] = { -- Bandit's Insignia - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40373"] = { -- Extract of Necromantic Power - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 15, pos = 2, }, ["40382"] = { -- Soul of the Dead - text = "(Probabilidad de que accione: 25%%, %s)", + text = "(Probabilidad de que accione: 25%%. %s.)", cooldown = 45, pos = 2, }, ["40682"] = { -- Sundial of the Exiled - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40684"] = { -- Mirror of Truth - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["40685"] = { -- The Egg of Mortal Essence - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40767"] = { -- Sonic Booster - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 50, pos = 1, }, ["40865"] = { -- Noise Machine - text = "(Probabilidad de que accione: 50%%, %s)", + text = "(Probabilidad de que accione: 50%%. %s.)", cooldown = 50, pos = 2, }, ["42987"] = { -- Darkmoon Card: Greatness - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 1, }, ["42989"] = { -- Darkmoon Card: Berserker! - text = "(Probabilidad de que accione: 50%%)", + text = "(Probabilidad de que accione: 50%%.)", cooldown = 0, pos = 2, }, ["42990"] = { -- Darkmoon Card: Death - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43573"] = { -- Tears of Bitter Anguish - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["43829"] = { -- Crusader's Locket - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43838"] = { -- Chuchu's Tiny Box of Horrors - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["44253"] = { -- Darkmoon Card: Greatness - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44254"] = { -- Darkmoon Card: Greatness - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44255"] = { -- Darkmoon Card: Greatness - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44912"] = { -- Flow of Knowledge - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["44914"] = { -- Anvil of Titans - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45131"] = { -- Jouster's Fury - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45286"] = { -- Pyrite Infuser - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45490"] = { -- Pandora's Plea - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 1, }, ["45507"] = { -- The General's Heart - text = "(Probabilidad de que accione: 5%%, %s)", + text = "(Probabilidad de que accione: 5%%. %s.)", cooldown = 50, pos = 2, }, ["45518"] = { -- Flare of the Heavens - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45522"] = { -- Blood of the Old God - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45535"] = { -- Show of Faith - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45609"] = { -- Comet's Trail - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["45866"] = { -- Elemental Focus Stone - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45929"] = { -- Sif's Remembrance - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45931"] = { -- Mjolnir Runestone - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["46038"] = { -- Dark Matter - text = "(Probabilidad de que accione: 15%%, %s)", + text = "(Probabilidad de que accione: 15%%. %s.)", cooldown = 45, pos = 2, }, ["47115"] = { -- Death's Verdict - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47131"] = { -- Death's Verdict - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47182"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47188"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47213"] = { -- Abyssal Rune - text = "(Probabilidad de que accione: 25%%, %s)", + text = "(Probabilidad de que accione: 25%%. %s.)", cooldown = 45, pos = 2, }, ["47214"] = { -- Banner of Victory - text = "(Probabilidad de que accione: 20%%, %s)", + text = "(Probabilidad de que accione: 20%%. %s.)", cooldown = 50, pos = 2, }, ["47215"] = { -- Tears of the Vanquished - text = "(Probabilidad de que accione: 25%%, %s)", + text = "(Probabilidad de que accione: 25%%. %s.)", cooldown = 45, pos = 1, }, ["47216"] = { -- The Black Heart - text = "(Probabilidad de que accione: 25%%, %s)", + text = "(Probabilidad de que accione: 25%%. %s.)", cooldown = 50, pos = 1, }, ["47303"] = { -- Death's Choice - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47316"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47464"] = { -- Death's Choice - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47477"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["49074"] = { -- Coren's Chromium Coaster - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["49076"] = { -- Mithril Pocketwatch - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49078"] = { -- Ancient Pickled Egg - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49310"] = { -- Purified Shard of the Scale - text = "(Probabilidad de que accione: 25%%, %s)", + text = "(Probabilidad de que accione: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49463"] = { -- Purified Shard of the Flame - text = "(Probabilidad de que accione: 25%%, %s)", + text = "(Probabilidad de que accione: 25%%. %s.)", cooldown = 50, pos = 3, }, db = { -- Shiny Shard of the Flame - text = "(Probabilidad de que accione: 25%%, %s)", + text = "(Probabilidad de que accione: 25%%. %s.)", cooldown = 50, pos = 2, }, ["49488"] = { -- Shiny Shard of the Scale - text = "(Probabilidad de que accione: 25%%, %s)", + text = "(Probabilidad de que accione: 25%%. %s.)", cooldown = 50, pos = 3, }, ["50198"] = { -- Needle-Encrusted Scorpion - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50341"] = { -- Unidentifiable Organ - text = "(Probabilidad de que accione: 60%%)", + text = "(Probabilidad de que accione: 60%%.)", cooldown = 0, pos = 1, }, ["50342"] = { -- Whispering Fanged Skull - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50343"] = { -- Whispering Fanged Skull - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50344"] = { -- Unidentifiable Organ - text = "(Probabilidad de que accione: 60%%)", + text = "(Probabilidad de que accione: 60%%.)", cooldown = 0, pos = 1, }, ["50348"] = { -- Dislodged Foreign Object - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50349"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50352"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50353"] = { -- Dislodged Foreign Object - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50358"] = { -- Purified Lunar Dust - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50359"] = { -- Althor's Abacus - text = "(Probabilidad de que accione: 30%%, %s)", + text = "(Probabilidad de que accione: 30%%. %s.)", cooldown = 45, pos = 2, }, ["50360"] = { -- Phylactery of the Nameless Lich - text = "(Probabilidad de que accione: 30%%, %s)", + text = "(Probabilidad de que accione: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50362"] = { -- Deathbringer's Will - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50363"] = { -- Deathbringer's Will - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50365"] = { -- Phylactery of the Nameless Lich - text = "(Probabilidad de que accione: 30%%, %s)", + text = "(Probabilidad de que accione: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50366"] = { -- Althor's Abacus - text = "(Probabilidad de que accione: 30%%, %s)", + text = "(Probabilidad de que accione: 30%%. %s.)", cooldown = 45, pos = 2, }, ["54569"] = { -- Sharpened Twilight Scale - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54571"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, ["54572"] = { -- Charred Twilight Scale - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54588"] = { -- Charred Twilight Scale - text = "(Probabilidad de que accione: 10%%, %s)", + text = "(Probabilidad de que accione: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54590"] = { -- Sharpened Twilight Scale - text = "(Probabilidad de que accione: 35%%, %s)", + text = "(Probabilidad de que accione: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54591"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, }, ["frFR"] = { ["1490"] = { -- Guardian Talisman - text = "(Chance d'occurence: 2%%)", + text = "(Chance d'occurence: 2%%.)", cooldown = 0, pos = 1, }, ["11302"] = { -- Uther's Strength - text = "(Chance d'occurence: 2%%)", + text = "(Chance d'occurence: 2%%.)", cooldown = 0, pos = 1, }, ["11810"] = { -- Force of Will - text = "(Chance d'occurence: 1%%)", + text = "(Chance d'occurence: 1%%.)", cooldown = 0, pos = 1, }, ["11815"] = { -- Hand of Justice - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["14557"] = { -- The Lion Horn of Stormwind - text = "(Chance d'occurence: 1%%)", + text = "(Chance d'occurence: 1%%.)", cooldown = 0, pos = 1, }, ["17774"] = { -- Mark of the Chosen - text = "(Chance d'occurence: 2%%)", + text = "(Chance d'occurence: 2%%.)", cooldown = 0, pos = 1, }, ["19288"] = { -- Darkmoon Card: Blue Dragon - text = "(Chance d'occurence: 2%%)", + text = "(Chance d'occurence: 2%%.)", cooldown = 0, pos = 1, }, ["27683"] = { -- Quagmirran's Eye - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["27896"] = { -- Alembic of Infernal Power - text = "(Chance d'occurence: 2%%)", + text = "(Chance d'occurence: 2%%.)", cooldown = 0, pos = 2, }, ["27922"] = { -- Mark of Defiance - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27924"] = { -- Mark of Defiance - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27926"] = { -- Mark of Vindication - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 25, pos = 2, }, ["27927"] = { -- Mark of Vindication - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 25, pos = 2, }, ["28034"] = { -- Hourglass of the Unraveller - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["28108"] = { -- Power Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28109"] = { -- Essence Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28190"] = { -- Scarab of the Infinite Cycle - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["28418"] = { -- Shiffar's Nexus-Horn - text = "(Chance d'occurence: 20%%, %s)", + text = "(Chance d'occurence: 20%%. %s.)", cooldown = 45, pos = 2, }, ["28785"] = { -- The Lightning Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["28823"] = { -- Eye of Gruul - text = "(Chance d'occurence: 2%%)", + text = "(Chance d'occurence: 2%%.)", cooldown = 0, pos = 2, }, ["28830"] = { -- Dragonspine Trophy - text = "(%s)", + text = "(%s.)", cooldown = 20, pos = 2, }, ["30447"] = { -- Tome of Fiery Redemption - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 1, }, ["30450"] = { -- Warp-Spring Coil - text = "(Chance d'occurence: 25%%, %s)", + text = "(Chance d'occurence: 25%%. %s.)", cooldown = 30, pos = 2, }, ["30619"] = { -- Fel Reaver's Piston - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 15, pos = 1, }, ["30626"] = { -- Sextant of Unstable Currents - text = "(Chance d'occurence: 20%%, %s)", + text = "(Chance d'occurence: 20%%. %s.)", cooldown = 45, pos = 2, }, ["30627"] = { -- Tsunami Talisman - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 3, }, ["30663"] = { -- Fathom-Brooch of the Tidewalker - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 40, pos = 1, }, ["30664"] = { -- Living Root of the Wildheart - text = "(Chance d'occurence: 3%%)", + text = "(Chance d'occurence: 3%%.)", cooldown = 0, pos = 1, }, ["31858"] = { -- Darkmoon Card: Vengeance - text = "(Chance d'occurence: 10%%)", + text = "(Chance d'occurence: 10%%.)", cooldown = 0, pos = 1, }, ["32485"] = { -- Ashtongue Talisman of Valor - text = "(Chance d'occurence: 25%%)", + text = "(Chance d'occurence: 25%%.)", cooldown = 0, pos = 1, }, ["32487"] = { -- Ashtongue Talisman of Swiftness - text = "(Chance d'occurence: 15%%)", + text = "(Chance d'occurence: 15%%.)", cooldown = 0, pos = 1, }, ["32488"] = { -- Ashtongue Talisman of Insight - text = "(Chance d'occurence: 50%%)", + text = "(Chance d'occurence: 50%%.)", cooldown = 0, pos = 1, }, ["32490"] = { -- Ashtongue Talisman of Acumen - text = "(Chance d'occurence: 10%%)", + text = "(Chance d'occurence: 10%%.)", cooldown = 0, pos = 1, }, ["32493"] = { -- Ashtongue Talisman of Shadows - text = "(Chance d'occurence: 20%%)", + text = "(Chance d'occurence: 20%%.)", cooldown = 0, pos = 1, }, ["32496"] = { -- Memento of Tyrande - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["32770"] = { -- Skyguard Silver Cross - text = "(Chance d'occurence: 50%%, %s)", + text = "(Chance d'occurence: 50%%. %s.)", cooldown = 10, pos = 2, }, ["32771"] = { -- Airman's Ribbon of Gallantry - text = "(Chance d'occurence: 50%%, %s)", + text = "(Chance d'occurence: 50%%. %s.)", cooldown = 10, pos = 2, }, ["34427"] = { -- Blackened Naaru Sliver - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34470"] = { -- Timbal's Focusing Crystal - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 15, pos = 1, }, ["34472"] = { -- Shard of Contempt - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34473"] = { -- Commendation of Kael'thas - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 1, }, ["37064"] = { -- Vestige of Haldor - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37111"] = { -- Soul Preserver - text = "(Chance d'occurence: 2%%)", + text = "(Chance d'occurence: 2%%.)", cooldown = 0, pos = 2, }, ["37220"] = { -- Essence of Gossamer - text = "(Chance d'occurence: 5%%, %s)", + text = "(Chance d'occurence: 5%%. %s.)", cooldown = 50, pos = 1, }, ["37264"] = { -- Pendulum of Telluric Currents - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37390"] = { -- Meteorite Whetstone - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37559"] = { -- Serrah's Star - text = "(Chance d'occurence: 45%%, %s)", + text = "(Chance d'occurence: 45%%. %s.)", cooldown = 45, pos = 2, }, ["37657"] = { -- Spark of Life - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["37660"] = { -- Forge Ember - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["37835"] = { -- Je'Tze's Bell - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 1, }, ["38071"] = { -- Valonforth's Remembrance - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["38072"] = { -- Thunder Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["38212"] = { -- Death Knight's Anguish - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["38358"] = { -- Arcane Revitalizer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38359"] = { -- Goblin Repetition Reducer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38674"] = { -- Soul Harvester's Charm - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["38675"] = { -- Signet of the Dark Brotherhood - text = "(Chance d'occurence: 30%%, %s)", + text = "(Chance d'occurence: 30%%. %s.)", cooldown = 45, pos = 2, }, ["39229"] = { -- Embrace of the Spider - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["39889"] = { -- Horn of Argent Fury - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 1, }, ["40255"] = { -- Dying Curse - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40256"] = { -- Grim Toll - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40258"] = { -- Forethought Talisman - text = "(Chance d'occurence: 20%%, %s)", + text = "(Chance d'occurence: 20%%. %s.)", cooldown = 45, pos = 2, }, ["40371"] = { -- Bandit's Insignia - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40373"] = { -- Extract of Necromantic Power - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 15, pos = 2, }, ["40382"] = { -- Soul of the Dead - text = "(Chance d'occurence: 25%%, %s)", + text = "(Chance d'occurence: 25%%. %s.)", cooldown = 45, pos = 2, }, ["40682"] = { -- Sundial of the Exiled - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40684"] = { -- Mirror of Truth - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["40685"] = { -- The Egg of Mortal Essence - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40767"] = { -- Sonic Booster - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 50, pos = 1, }, ["40865"] = { -- Noise Machine - text = "(Chance d'occurence: 50%%, %s)", + text = "(Chance d'occurence: 50%%. %s.)", cooldown = 50, pos = 2, }, ["42987"] = { -- Darkmoon Card: Greatness - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 1, }, ["42989"] = { -- Darkmoon Card: Berserker! - text = "(Chance d'occurence: 50%%)", + text = "(Chance d'occurence: 50%%.)", cooldown = 0, pos = 2, }, ["42990"] = { -- Darkmoon Card: Death - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43573"] = { -- Tears of Bitter Anguish - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["43829"] = { -- Crusader's Locket - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43838"] = { -- Chuchu's Tiny Box of Horrors - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["44253"] = { -- Darkmoon Card: Greatness - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44254"] = { -- Darkmoon Card: Greatness - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44255"] = { -- Darkmoon Card: Greatness - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44912"] = { -- Flow of Knowledge - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["44914"] = { -- Anvil of Titans - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45131"] = { -- Jouster's Fury - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45286"] = { -- Pyrite Infuser - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45490"] = { -- Pandora's Plea - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 1, }, ["45507"] = { -- The General's Heart - text = "(Chance d'occurence: 5%%, %s)", + text = "(Chance d'occurence: 5%%. %s.)", cooldown = 50, pos = 2, }, ["45518"] = { -- Flare of the Heavens - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45522"] = { -- Blood of the Old God - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45535"] = { -- Show of Faith - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45609"] = { -- Comet's Trail - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["45866"] = { -- Elemental Focus Stone - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45929"] = { -- Sif's Remembrance - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45931"] = { -- Mjolnir Runestone - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["46038"] = { -- Dark Matter - text = "(Chance d'occurence: 15%%, %s)", + text = "(Chance d'occurence: 15%%. %s.)", cooldown = 45, pos = 2, }, ["47115"] = { -- Death's Verdict - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47131"] = { -- Death's Verdict - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47182"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47188"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47213"] = { -- Abyssal Rune - text = "(Chance d'occurence: 25%%, %s)", + text = "(Chance d'occurence: 25%%. %s.)", cooldown = 45, pos = 2, }, ["47214"] = { -- Banner of Victory - text = "(Chance d'occurence: 20%%, %s)", + text = "(Chance d'occurence: 20%%. %s.)", cooldown = 50, pos = 2, }, ["47215"] = { -- Tears of the Vanquished - text = "(Chance d'occurence: 25%%, %s)", + text = "(Chance d'occurence: 25%%. %s.)", cooldown = 45, pos = 1, }, ["47216"] = { -- The Black Heart - text = "(Chance d'occurence: 25%%, %s)", + text = "(Chance d'occurence: 25%%. %s.)", cooldown = 50, pos = 1, }, ["47303"] = { -- Death's Choice - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47316"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47464"] = { -- Death's Choice - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47477"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["49074"] = { -- Coren's Chromium Coaster - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["49076"] = { -- Mithril Pocketwatch - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49078"] = { -- Ancient Pickled Egg - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49310"] = { -- Purified Shard of the Scale - text = "(Chance d'occurence: 25%%, %s)", + text = "(Chance d'occurence: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49463"] = { -- Purified Shard of the Flame - text = "(Chance d'occurence: 25%%, %s)", + text = "(Chance d'occurence: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49464"] = { -- Shiny Shard of the Flame - text = "(Chance d'occurence: 25%%, %s)", + text = "(Chance d'occurence: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49488"] = { -- Shiny Shard of the Scale - text = "(Chance d'occurence: 25%%, %s)", + text = "(Chance d'occurence: 25%%. %s.)", cooldown = 50, pos = 3, }, ["50198"] = { -- Needle-Encrusted Scorpion - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50341"] = { -- Unidentifiable Organ - text = "(Chance d'occurence: 60%%)", + text = "(Chance d'occurence: 60%%.)", cooldown = 0, pos = 1, }, ["50342"] = { -- Whispering Fanged Skull - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50343"] = { -- Whispering Fanged Skull - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50344"] = { -- Unidentifiable Organ - text = "(Chance d'occurence: 60%%)", + text = "(Chance d'occurence: 60%%.)", cooldown = 0, pos = 1, }, ["50348"] = { -- Dislodged Foreign Object - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50349"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50352"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50353"] = { -- Dislodged Foreign Object - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50358"] = { -- Purified Lunar Dust - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50359"] = { -- Althor's Abacus - text = "(Chance d'occurence: 30%%, %s)", + text = "(Chance d'occurence: 30%%. %s.)", cooldown = 45, pos = 2, }, ["50360"] = { -- Phylactery of the Nameless Lich - text = "(Chance d'occurence: 30%%, %s)", + text = "(Chance d'occurence: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50362"] = { -- Deathbringer's Will - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50363"] = { -- Deathbringer's Will - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50365"] = { -- Phylactery of the Nameless Lich - text = "(Chance d'occurence: 30%%, %s)", + text = "(Chance d'occurence: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50366"] = { -- Althor's Abacus - text = "(Chance d'occurence: 30%%, %s)", + text = "(Chance d'occurence: 30%%. %s.)", cooldown = 45, pos = 2, }, ["54569"] = { -- Sharpened Twilight Scale - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54571"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, ["54572"] = { -- Charred Twilight Scale - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54588"] = { -- Charred Twilight Scale - text = "(Chance d'occurence: 10%%, %s)", + text = "(Chance d'occurence: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54590"] = { -- Sharpened Twilight Scale - text = "(Chance d'occurence: 35%%, %s)", + text = "(Chance d'occurence: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54591"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, }, ["koKR"] = { ["1490"] = { -- Guardian Talisman - text = "(효과 발동 확률: 2%%)", + text = "(효과 발동 확률: 2%%.)", cooldown = 0, pos = 1, }, ["11302"] = { -- Uther's Strength - text = "(효과 발동 확률: 2%%)", + text = "(효과 발동 확률: 2%%.)", cooldown = 0, pos = 1, }, ["11810"] = { -- Force of Will - text = "(효과 발동 확률: 1%%)", + text = "(효과 발동 확률: 1%%.)", cooldown = 0, pos = 1, }, ["11815"] = { -- Hand of Justice - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["14557"] = { -- The Lion Horn of Stormwind - text = "(효과 발동 확률: 1%%)", + text = "(효과 발동 확률: 1%%.)", cooldown = 0, pos = 1, }, ["17774"] = { -- Mark of the Chosen - text = "(효과 발동 확률: 2%%)", + text = "(효과 발동 확률: 2%%.)", cooldown = 0, pos = 1, }, ["19288"] = { -- Darkmoon Card: Blue Dragon - text = "(효과 발동 확률: 2%%)", + text = "(효과 발동 확률: 2%%.)", cooldown = 0, pos = 1, }, ["27683"] = { -- Quagmirran's Eye - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["27896"] = { -- Alembic of Infernal Power - text = "(효과 발동 확률: 2%%)", + text = "(효과 발동 확률: 2%%.)", cooldown = 0, pos = 2, }, ["27922"] = { -- Mark of Defiance - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27924"] = { -- Mark of Defiance - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27926"] = { -- Mark of Vindication - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 25, pos = 2, }, ["27927"] = { -- Mark of Vindication - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 25, pos = 2, }, ["28034"] = { -- Hourglass of the Unraveller - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["28108"] = { -- Power Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28109"] = { -- Essence Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28190"] = { -- Scarab of the Infinite Cycle - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["28418"] = { -- Shiffar's Nexus-Horn - text = "(효과 발동 확률: 20%%, %s)", + text = "(효과 발동 확률: 20%%. %s.)", cooldown = 45, pos = 2, }, ["28785"] = { -- The Lightning Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["28823"] = { -- Eye of Gruul - text = "(효과 발동 확률: 2%%)", + text = "(효과 발동 확률: 2%%.)", cooldown = 0, pos = 2, }, ["28830"] = { -- Dragonspine Trophy - text = "(%s)", + text = "(%s.)", cooldown = 20, pos = 2, }, ["30447"] = { -- Tome of Fiery Redemption - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 1, }, ["30450"] = { -- Warp-Spring Coil - text = "(효과 발동 확률: 25%%, %s)", + text = "(효과 발동 확률: 25%%. %s.)", cooldown = 30, pos = 2, }, ["30619"] = { -- Fel Reaver's Piston - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 15, pos = 1, }, ["30626"] = { -- Sextant of Unstable Currents - text = "(효과 발동 확률: 20%%, %s)", + text = "(효과 발동 확률: 20%%. %s.)", cooldown = 45, pos = 2, }, ["30627"] = { -- Tsunami Talisman - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 3, }, ["30663"] = { -- Fathom-Brooch of the Tidewalker - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 40, pos = 1, }, ["30664"] = { -- Living Root of the Wildheart - text = "(효과 발동 확률: 3%%)", + text = "(효과 발동 확률: 3%%.)", cooldown = 0, pos = 1, }, ["31858"] = { -- Darkmoon Card: Vengeance - text = "(효과 발동 확률: 10%%)", + text = "(효과 발동 확률: 10%%.)", cooldown = 0, pos = 1, }, ["32485"] = { -- Ashtongue Talisman of Valor - text = "(효과 발동 확률: 25%%)", + text = "(효과 발동 확률: 25%%.)", cooldown = 0, pos = 1, }, ["32487"] = { -- Ashtongue Talisman of Swiftness - text = "(효과 발동 확률: 15%%)", + text = "(효과 발동 확률: 15%%.)", cooldown = 0, pos = 1, }, ["32488"] = { -- Ashtongue Talisman of Insight - text = "(효과 발동 확률: 50%%)", + text = "(효과 발동 확률: 50%%.)", cooldown = 0, pos = 1, }, ["32490"] = { -- Ashtongue Talisman of Acumen - text = "(효과 발동 확률: 10%%)", + text = "(효과 발동 확률: 10%%.)", cooldown = 0, pos = 1, }, ["32493"] = { -- Ashtongue Talisman of Shadows - text = "(효과 발동 확률: 20%%)", + text = "(효과 발동 확률: 20%%.)", cooldown = 0, pos = 1, }, ["32496"] = { -- Memento of Tyrande - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["32770"] = { -- Skyguard Silver Cross - text = "(효과 발동 확률: 50%%, %s)", + text = "(효과 발동 확률: 50%%. %s.)", cooldown = 10, pos = 2, }, ["32771"] = { -- Airman's Ribbon of Gallantry - text = "(효과 발동 확률: 50%%, %s)", + text = "(효과 발동 확률: 50%%. %s.)", cooldown = 10, pos = 2, }, ["34427"] = { -- Blackened Naaru Sliver - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34470"] = { -- Timbal's Focusing Crystal - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 15, pos = 1, }, ["34472"] = { -- Shard of Contempt - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34473"] = { -- Commendation of Kael'thas - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 1, }, ["37064"] = { -- Vestige of Haldor - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37111"] = { -- Soul Preserver - text = "(효과 발동 확률: 2%%)", + text = "(효과 발동 확률: 2%%.)", cooldown = 0, pos = 2, }, ["37220"] = { -- Essence of Gossamer - text = "(효과 발동 확률: 5%%, %s)", + text = "(효과 발동 확률: 5%%. %s.)", cooldown = 50, pos = 1, }, ["37264"] = { -- Pendulum of Telluric Currents - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37390"] = { -- Meteorite Whetstone - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37559"] = { -- Serrah's Star - text = "(효과 발동 확률: 45%%, %s)", + text = "(효과 발동 확률: 45%%. %s.)", cooldown = 45, pos = 2, }, ["37657"] = { -- Spark of Life - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["37660"] = { -- Forge Ember - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["37835"] = { -- Je'Tze's Bell - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 1, }, ["38071"] = { -- Valonforth's Remembrance - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["38072"] = { -- Thunder Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["38212"] = { -- Death Knight's Anguish - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["38358"] = { -- Arcane Revitalizer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38359"] = { -- Goblin Repetition Reducer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38674"] = { -- Soul Harvester's Charm - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["38675"] = { -- Signet of the Dark Brotherhood - text = "(효과 발동 확률: 30%%, %s)", + text = "(효과 발동 확률: 30%%. %s.)", cooldown = 45, pos = 2, }, ["39229"] = { -- Embrace of the Spider - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["39889"] = { -- Horn of Argent Fury - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 1, }, ["40255"] = { -- Dying Curse - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40256"] = { -- Grim Toll - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40258"] = { -- Forethought Talisman - text = "(효과 발동 확률: 20%%, %s)", + text = "(효과 발동 확률: 20%%. %s.)", cooldown = 45, pos = 2, }, ["40371"] = { -- Bandit's Insignia - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40373"] = { -- Extract of Necromantic Power - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 15, pos = 2, }, ["40382"] = { -- Soul of the Dead - text = "(효과 발동 확률: 25%%, %s)", + text = "(효과 발동 확률: 25%%. %s.)", cooldown = 45, pos = 2, }, ["40682"] = { -- Sundial of the Exiled - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40684"] = { -- Mirror of Truth - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["40685"] = { -- The Egg of Mortal Essence - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40767"] = { -- Sonic Booster - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 50, pos = 1, }, ["40865"] = { -- Noise Machine - text = "(효과 발동 확률: 50%%, %s)", + text = "(효과 발동 확률: 50%%. %s.)", cooldown = 50, pos = 2, }, ["42987"] = { -- Darkmoon Card: Greatness - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 1, }, ["42989"] = { -- Darkmoon Card: Berserker! - text = "(효과 발동 확률: 50%%)", + text = "(효과 발동 확률: 50%%.)", cooldown = 0, pos = 2, }, ["42990"] = { -- Darkmoon Card: Death - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43573"] = { -- Tears of Bitter Anguish - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["43829"] = { -- Crusader's Locket - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43838"] = { -- Chuchu's Tiny Box of Horrors - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["44253"] = { -- Darkmoon Card: Greatness - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44254"] = { -- Darkmoon Card: Greatness - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44255"] = { -- Darkmoon Card: Greatness - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44912"] = { -- Flow of Knowledge - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["44914"] = { -- Anvil of Titans - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45131"] = { -- Jouster's Fury - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45286"] = { -- Pyrite Infuser - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45490"] = { -- Pandora's Plea - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 1, }, ["45507"] = { -- The General's Heart - text = "(효과 발동 확률: 5%%, %s)", + text = "(효과 발동 확률: 5%%. %s.)", cooldown = 50, pos = 2, }, ["45518"] = { -- Flare of the Heavens - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45522"] = { -- Blood of the Old God - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45535"] = { -- Show of Faith - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45609"] = { -- Comet's Trail - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["45866"] = { -- Elemental Focus Stone - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45929"] = { -- Sif's Remembrance - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45931"] = { -- Mjolnir Runestone - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["46038"] = { -- Dark Matter - text = "(효과 발동 확률: 15%%, %s)", + text = "(효과 발동 확률: 15%%. %s.)", cooldown = 45, pos = 2, }, ["47115"] = { -- Death's Verdict - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47131"] = { -- Death's Verdict - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47182"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47188"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47213"] = { -- Abyssal Rune - text = "(효과 발동 확률: 25%%, %s)", + text = "(효과 발동 확률: 25%%. %s.)", cooldown = 45, pos = 2, }, ["47214"] = { -- Banner of Victory - text = "(효과 발동 확률: 20%%, %s)", + text = "(효과 발동 확률: 20%%. %s.)", cooldown = 50, pos = 2, }, ["47215"] = { -- Tears of the Vanquished - text = "(효과 발동 확률: 25%%, %s)", + text = "(효과 발동 확률: 25%%. %s.)", cooldown = 45, pos = 1, }, ["47216"] = { -- The Black Heart - text = "(효과 발동 확률: 25%%, %s)", + text = "(효과 발동 확률: 25%%. %s.)", cooldown = 50, pos = 1, }, ["47303"] = { -- Death's Choice - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47316"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47464"] = { -- Death's Choice - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47477"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["49074"] = { -- Coren's Chromium Coaster - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["49076"] = { -- Mithril Pocketwatch - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49078"] = { -- Ancient Pickled Egg - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49310"] = { -- Purified Shard of the Scale - text = "(효과 발동 확률: 25%%, %s)", + text = "(효과 발동 확률: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49463"] = { -- Purified Shard of the Flame - text = "(효과 발동 확률: 25%%, %s)", + text = "(효과 발동 확률: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49464"] = { -- Shiny Shard of the Flame - text = "(효과 발동 확률: 25%%, %s)", + text = "(효과 발동 확률: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49488"] = { -- Shiny Shard of the Scale - text = "(효과 발동 확률: 25%%, %s)", + text = "(효과 발동 확률: 25%%. %s.)", cooldown = 50, pos = 3, }, ["50198"] = { -- Needle-Encrusted Scorpion - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50341"] = { -- Unidentifiable Organ - text = "(효과 발동 확률: 60%%)", + text = "(효과 발동 확률: 60%%.)", cooldown = 0, pos = 1, }, ["50342"] = { -- Whispering Fanged Skull - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50343"] = { -- Whispering Fanged Skull - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50344"] = { -- Unidentifiable Organ - text = "(효과 발동 확률: 60%%)", + text = "(효과 발동 확률: 60%%.)", cooldown = 0, pos = 1, }, ["50348"] = { -- Dislodged Foreign Object - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50349"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50352"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50353"] = { -- Dislodged Foreign Object - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50358"] = { -- Purified Lunar Dust - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50359"] = { -- Althor's Abacus - text = "(효과 발동 확률: 30%%, %s)", + text = "(효과 발동 확률: 30%%. %s.)", cooldown = 45, pos = 2, }, ["50360"] = { -- Phylactery of the Nameless Lich - text = "(효과 발동 확률: 30%%, %s)", + text = "(효과 발동 확률: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50362"] = { -- Deathbringer's Will - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50363"] = { -- Deathbringer's Will - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50365"] = { -- Phylactery of the Nameless Lich - text = "(효과 발동 확률: 30%%, %s)", + text = "(효과 발동 확률: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50366"] = { -- Althor's Abacus - text = "(효과 발동 확률: 30%%, %s)", + text = "(효과 발동 확률: 30%%. %s.)", cooldown = 45, pos = 2, }, ["54569"] = { -- Sharpened Twilight Scale - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54571"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, ["54572"] = { -- Charred Twilight Scale - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54588"] = { -- Charred Twilight Scale - text = "(효과 발동 확률: 10%%, %s)", + text = "(효과 발동 확률: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54590"] = { -- Sharpened Twilight Scale - text = "(효과 발동 확률: 35%%, %s)", + text = "(효과 발동 확률: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54591"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, }, ["ptBR"] = { ["1490"] = { -- Guardian Talisman - text = "(Chance de ativar: 2%%)", + text = "(Chance de ativar: 2%%.)", cooldown = 0, pos = 1, }, ["11302"] = { -- Uther's Strength - text = "(Chance de ativar: 2%%)", + text = "(Chance de ativar: 2%%.)", cooldown = 0, pos = 1, }, ["11810"] = { -- Force of Will - text = "(Chance de ativar: 1%%)", + text = "(Chance de ativar: 1%%.)", cooldown = 0, pos = 1, }, ["11815"] = { -- Hand of Justice - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["14557"] = { -- The Lion Horn of Stormwind - text = "(Chance de ativar: 1%%)", + text = "(Chance de ativar: 1%%.)", cooldown = 0, pos = 1, }, ["17774"] = { -- Mark of the Chosen - text = "(Chance de ativar: 2%%)", + text = "(Chance de ativar: 2%%.)", cooldown = 0, pos = 1, }, ["19288"] = { -- Darkmoon Card: Blue Dragon - text = "(Chance de ativar: 2%%)", + text = "(Chance de ativar: 2%%.)", cooldown = 0, pos = 1, }, ["27683"] = { -- Quagmirran's Eye - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["27896"] = { -- Alembic of Infernal Power - text = "(Chance de ativar: 2%%)", + text = "(Chance de ativar: 2%%.)", cooldown = 0, pos = 2, }, ["27922"] = { -- Mark of Defiance - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27924"] = { -- Mark of Defiance - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27926"] = { -- Mark of Vindication - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 25, pos = 2, }, ["27927"] = { -- Mark of Vindication - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 25, pos = 2, }, ["28034"] = { -- Hourglass of the Unraveller - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["28108"] = { -- Power Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28109"] = { -- Essence Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28190"] = { -- Scarab of the Infinite Cycle - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["28418"] = { -- Shiffar's Nexus-Horn - text = "(Chance de ativar: 20%%, %s)", + text = "(Chance de ativar: 20%%. %s.)", cooldown = 45, pos = 2, }, ["28785"] = { -- The Lightning Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["28823"] = { -- Eye of Gruul - text = "(Chance de ativar: 2%%)", + text = "(Chance de ativar: 2%%.)", cooldown = 0, pos = 2, }, ["28830"] = { -- Dragonspine Trophy - text = "(%s)", + text = "(%s.)", cooldown = 20, pos = 2, }, ["30447"] = { -- Tome of Fiery Redemption - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 1, }, ["30450"] = { -- Warp-Spring Coil - text = "(Chance de ativar: 25%%, %s)", + text = "(Chance de ativar: 25%%. %s.)", cooldown = 30, pos = 2, }, ["30619"] = { -- Fel Reaver's Piston - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 15, pos = 1, }, ["30626"] = { -- Sextant of Unstable Currents - text = "(Chance de ativar: 20%%, %s)", + text = "(Chance de ativar: 20%%. %s.)", cooldown = 45, pos = 2, }, ["30627"] = { -- Tsunami Talisman - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 3, }, ["30663"] = { -- Fathom-Brooch of the Tidewalker - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 40, pos = 1, }, ["30664"] = { -- Living Root of the Wildheart - text = "(Chance de ativar: 3%%)", + text = "(Chance de ativar: 3%%.)", cooldown = 0, pos = 1, }, ["31858"] = { -- Darkmoon Card: Vengeance - text = "(Chance de ativar: 10%%)", + text = "(Chance de ativar: 10%%.)", cooldown = 0, pos = 1, }, ["32485"] = { -- Ashtongue Talisman of Valor - text = "(Chance de ativar: 25%%)", + text = "(Chance de ativar: 25%%.)", cooldown = 0, pos = 1, }, ["32487"] = { -- Ashtongue Talisman of Swiftness - text = "(Chance de ativar: 15%%)", + text = "(Chance de ativar: 15%%.)", cooldown = 0, pos = 1, }, ["32488"] = { -- Ashtongue Talisman of Insight - text = "(Chance de ativar: 50%%)", + text = "(Chance de ativar: 50%%.)", cooldown = 0, pos = 1, }, ["32490"] = { -- Ashtongue Talisman of Acumen - text = "(Chance de ativar: 10%%)", + text = "(Chance de ativar: 10%%.)", cooldown = 0, pos = 1, }, ["32493"] = { -- Ashtongue Talisman of Shadows - text = "(Chance de ativar: 20%%)", + text = "(Chance de ativar: 20%%.)", cooldown = 0, pos = 1, }, ["32496"] = { -- Memento of Tyrande - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["32770"] = { -- Skyguard Silver Cross - text = "(Chance de ativar: 50%%, %s)", + text = "(Chance de ativar: 50%%. %s.)", cooldown = 10, pos = 2, }, ["32771"] = { -- Airman's Ribbon of Gallantry - text = "(Chance de ativar: 50%%, %s)", + text = "(Chance de ativar: 50%%. %s.)", cooldown = 10, pos = 2, }, ["34427"] = { -- Blackened Naaru Sliver - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34470"] = { -- Timbal's Focusing Crystal - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 15, pos = 1, }, ["34472"] = { -- Shard of Contempt - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34473"] = { -- Commendation of Kael'thas - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 1, }, ["37064"] = { -- Vestige of Haldor - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37111"] = { -- Soul Preserver - text = "(Chance de ativar: 2%%)", + text = "(Chance de ativar: 2%%.)", cooldown = 0, pos = 2, }, ["37220"] = { -- Essence of Gossamer - text = "(Chance de ativar: 5%%, %s)", + text = "(Chance de ativar: 5%%. %s.)", cooldown = 50, pos = 1, }, ["37264"] = { -- Pendulum of Telluric Currents - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37390"] = { -- Meteorite Whetstone - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37559"] = { -- Serrah's Star - text = "(Chance de ativar: 45%%, %s)", + text = "(Chance de ativar: 45%%. %s.)", cooldown = 45, pos = 2, }, ["37657"] = { -- Spark of Life - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["37660"] = { -- Forge Ember - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["37835"] = { -- Je'Tze's Bell - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 1, }, ["38071"] = { -- Valonforth's Remembrance - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["38072"] = { -- Thunder Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["38212"] = { -- Death Knight's Anguish - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["38358"] = { -- Arcane Revitalizer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38359"] = { -- Goblin Repetition Reducer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38674"] = { -- Soul Harvester's Charm - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["38675"] = { -- Signet of the Dark Brotherhood - text = "(Chance de ativar: 30%%, %s)", + text = "(Chance de ativar: 30%%. %s.)", cooldown = 45, pos = 2, }, ["39229"] = { -- Embrace of the Spider - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["39889"] = { -- Horn of Argent Fury - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 1, }, ["40255"] = { -- Dying Curse - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40256"] = { -- Grim Toll - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40258"] = { -- Forethought Talisman - text = "(Chance de ativar: 20%%, %s)", + text = "(Chance de ativar: 20%%. %s.)", cooldown = 45, pos = 2, }, ["40371"] = { -- Bandit's Insignia - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40373"] = { -- Extract of Necromantic Power - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 15, pos = 2, }, ["40382"] = { -- Soul of the Dead - text = "(Chance de ativar: 25%%, %s)", + text = "(Chance de ativar: 25%%. %s.)", cooldown = 45, pos = 2, }, ["40682"] = { -- Sundial of the Exiled - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40684"] = { -- Mirror of Truth - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["40685"] = { -- The Egg of Mortal Essence - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40767"] = { -- Sonic Booster - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 50, pos = 1, }, ["40865"] = { -- Noise Machine - text = "(Chance de ativar: 50%%, %s)", + text = "(Chance de ativar: 50%%. %s.)", cooldown = 50, pos = 2, }, ["42987"] = { -- Darkmoon Card: Greatness - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 1, }, ["42989"] = { -- Darkmoon Card: Berserker! - text = "(Chance de ativar: 50%%)", + text = "(Chance de ativar: 50%%.)", cooldown = 0, pos = 2, }, ["42990"] = { -- Darkmoon Card: Death - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43573"] = { -- Tears of Bitter Anguish - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["43829"] = { -- Crusader's Locket - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43838"] = { -- Chuchu's Tiny Box of Horrors - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["44253"] = { -- Darkmoon Card: Greatness - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44254"] = { -- Darkmoon Card: Greatness - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44255"] = { -- Darkmoon Card: Greatness - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44912"] = { -- Flow of Knowledge - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["44914"] = { -- Anvil of Titans - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45131"] = { -- Jouster's Fury - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45286"] = { -- Pyrite Infuser - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45490"] = { -- Pandora's Plea - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 1, }, ["45507"] = { -- The General's Heart - text = "(Chance de ativar: 5%%, %s)", + text = "(Chance de ativar: 5%%. %s.)", cooldown = 50, pos = 2, }, ["45518"] = { -- Flare of the Heavens - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45522"] = { -- Blood of the Old God - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45535"] = { -- Show of Faith - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45609"] = { -- Comet's Trail - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["45866"] = { -- Elemental Focus Stone - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45929"] = { -- Sif's Remembrance - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45931"] = { -- Mjolnir Runestone - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["46038"] = { -- Dark Matter - text = "(Chance de ativar: 15%%, %s)", + text = "(Chance de ativar: 15%%. %s.)", cooldown = 45, pos = 2, }, ["47115"] = { -- Death's Verdict - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47131"] = { -- Death's Verdict - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47182"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47188"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47213"] = { -- Abyssal Rune - text = "(Chance de ativar: 25%%, %s)", + text = "(Chance de ativar: 25%%. %s.)", cooldown = 45, pos = 2, }, ["47214"] = { -- Banner of Victory - text = "(Chance de ativar: 20%%, %s)", + text = "(Chance de ativar: 20%%. %s.)", cooldown = 50, pos = 2, }, ["47215"] = { -- Tears of the Vanquished - text = "(Chance de ativar: 25%%, %s)", + text = "(Chance de ativar: 25%%. %s.)", cooldown = 45, pos = 1, }, ["47216"] = { -- The Black Heart - text = "(Chance de ativar: 25%%, %s)", + text = "(Chance de ativar: 25%%. %s.)", cooldown = 50, pos = 1, }, ["47303"] = { -- Death's Choice - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47316"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47464"] = { -- Death's Choice - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47477"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["49074"] = { -- Coren's Chromium Coaster - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["49076"] = { -- Mithril Pocketwatch - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49078"] = { -- Ancient Pickled Egg - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49310"] = { -- Purified Shard of the Scale - text = "(Chance de ativar: 25%%, %s)", + text = "(Chance de ativar: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49463"] = { -- Purified Shard of the Flame - text = "(Chance de ativar: 25%%, %s)", + text = "(Chance de ativar: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49464"] = { -- Shiny Shard of the Flame - text = "(Chance de ativar: 25%%, %s)", + text = "(Chance de ativar: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49488"] = { -- Shiny Shard of the Scale - text = "(Chance de ativar: 25%%, %s)", + text = "(Chance de ativar: 25%%. %s.)", cooldown = 50, pos = 3, }, ["50198"] = { -- Needle-Encrusted Scorpion - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50341"] = { -- Unidentifiable Organ - text = "(Chance de ativar: 60%%)", + text = "(Chance de ativar: 60%%.)", cooldown = 0, pos = 1, }, ["50342"] = { -- Whispering Fanged Skull - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50343"] = { -- Whispering Fanged Skull - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50344"] = { -- Unidentifiable Organ - text = "(Chance de ativar: 60%%)", + text = "(Chance de ativar: 60%%.)", cooldown = 0, pos = 1, }, ["50348"] = { -- Dislodged Foreign Object - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50349"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50352"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50353"] = { -- Dislodged Foreign Object - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50358"] = { -- Purified Lunar Dust - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50359"] = { -- Althor's Abacus - text = "(Chance de ativar: 30%%, %s)", + text = "(Chance de ativar: 30%%. %s.)", cooldown = 45, pos = 2, }, ["50360"] = { -- Phylactery of the Nameless Lich - text = "(Chance de ativar: 30%%, %s)", + text = "(Chance de ativar: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50362"] = { -- Deathbringer's Will - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50363"] = { -- Deathbringer's Will - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50365"] = { -- Phylactery of the Nameless Lich - text = "(Chance de ativar: 30%%, %s)", + text = "(Chance de ativar: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50366"] = { -- Althor's Abacus - text = "(Chance de ativar: 30%%, %s)", + text = "(Chance de ativar: 30%%. %s.)", cooldown = 45, pos = 2, }, ["54569"] = { -- Sharpened Twilight Scale - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54571"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, ["54572"] = { -- Charred Twilight Scale - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54588"] = { -- Charred Twilight Scale - text = "(Chance de ativar: 10%%, %s)", + text = "(Chance de ativar: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54590"] = { -- Sharpened Twilight Scale - text = "(Chance de ativar: 35%%, %s)", + text = "(Chance de ativar: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54591"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, }, ["ruRU"] = { ["1490"] = { -- Guardian Talisman - text = "(Вероятность срабатывания: 2%%)", + text = "(Вероятность срабатывания: 2%%.)", cooldown = 0, pos = 1, }, ["11302"] = { -- Uther's Strength - text = "(Вероятность срабатывания: 2%%)", + text = "(Вероятность срабатывания: 2%%.)", cooldown = 0, pos = 1, }, ["11810"] = { -- Force of Will - text = "(Вероятность срабатывания: 1%%)", + text = "(Вероятность срабатывания: 1%%.)", cooldown = 0, pos = 1, }, ["11815"] = { -- Hand of Justice - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["14557"] = { -- The Lion Horn of Stormwind - text = "(Вероятность срабатывания: 1%%)", + text = "(Вероятность срабатывания: 1%%.)", cooldown = 0, pos = 1, }, ["17774"] = { -- Mark of the Chosen - text = "(Вероятность срабатывания: 2%%)", + text = "(Вероятность срабатывания: 2%%.)", cooldown = 0, pos = 1, }, ["19288"] = { -- Darkmoon Card: Blue Dragon - text = "(Вероятность срабатывания: 2%%)", + text = "(Вероятность срабатывания: 2%%.)", cooldown = 0, pos = 1, }, ["27683"] = { -- Quagmirran's Eye - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["27896"] = { -- Alembic of Infernal Power - text = "(Вероятность срабатывания: 2%%)", + text = "(Вероятность срабатывания: 2%%.)", cooldown = 0, pos = 2, }, ["27922"] = { -- Mark of Defiance - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27924"] = { -- Mark of Defiance - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 17, pos = 2, }, ["27926"] = { -- Mark of Vindication - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 25, pos = 2, }, ["27927"] = { -- Mark of Vindication - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 25, pos = 2, }, ["28034"] = { -- Hourglass of the Unraveller - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["28108"] = { -- Power Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28109"] = { -- Essence Infused Mushroom - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 1, }, ["28190"] = { -- Scarab of the Infinite Cycle - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["28418"] = { -- Shiffar's Nexus-Horn - text = "(Вероятность срабатывания: 20%%, %s)", + text = "(Вероятность срабатывания: 20%%. %s.)", cooldown = 45, pos = 2, }, ["28785"] = { -- The Lightning Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["28823"] = { -- Eye of Gruul - text = "(Вероятность срабатывания: 2%%)", + text = "(Вероятность срабатывания: 2%%.)", cooldown = 0, pos = 2, }, ["28830"] = { -- Dragonspine Trophy - text = "(%s)", + text = "(%s.)", cooldown = 20, pos = 2, }, ["30447"] = { -- Tome of Fiery Redemption - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 1, }, ["30450"] = { -- Warp-Spring Coil - text = "(Вероятность срабатывания: 25%%, %s)", + text = "(Вероятность срабатывания: 25%%. %s.)", cooldown = 30, pos = 2, }, ["30619"] = { -- Fel Reaver's Piston - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 15, pos = 1, }, ["30626"] = { -- Sextant of Unstable Currents - text = "(Вероятность срабатывания: 20%%, %s)", + text = "(Вероятность срабатывания: 20%%. %s.)", cooldown = 45, pos = 2, }, ["30627"] = { -- Tsunami Talisman - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 3, }, ["30663"] = { -- Fathom-Brooch of the Tidewalker - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 40, pos = 1, }, ["30664"] = { -- Living Root of the Wildheart - text = "(Вероятность срабатывания: 3%%)", + text = "(Вероятность срабатывания: 3%%.)", cooldown = 0, pos = 1, }, ["31858"] = { -- Darkmoon Card: Vengeance - text = "(Вероятность срабатывания: 10%%)", + text = "(Вероятность срабатывания: 10%%.)", cooldown = 0, pos = 1, }, ["32485"] = { -- Ashtongue Talisman of Valor - text = "(Вероятность срабатывания: 25%%)", + text = "(Вероятность срабатывания: 25%%.)", cooldown = 0, pos = 1, }, ["32487"] = { -- Ashtongue Talisman of Swiftness - text = "(Вероятность срабатывания: 15%%)", + text = "(Вероятность срабатывания: 15%%.)", cooldown = 0, pos = 1, }, ["32488"] = { -- Ashtongue Talisman of Insight - text = "(Вероятность срабатывания: 50%%)", + text = "(Вероятность срабатывания: 50%%.)", cooldown = 0, pos = 1, }, ["32490"] = { -- Ashtongue Talisman of Acumen - text = "(Вероятность срабатывания: 10%%)", + text = "(Вероятность срабатывания: 10%%.)", cooldown = 0, pos = 1, }, ["32493"] = { -- Ashtongue Talisman of Shadows - text = "(Вероятность срабатывания: 20%%)", + text = "(Вероятность срабатывания: 20%%.)", cooldown = 0, pos = 1, }, ["32496"] = { -- Memento of Tyrande - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["32770"] = { -- Skyguard Silver Cross - text = "(Вероятность срабатывания: 50%%, %s)", + text = "(Вероятность срабатывания: 50%%. %s.)", cooldown = 10, pos = 2, }, ["32771"] = { -- Airman's Ribbon of Gallantry - text = "(Вероятность срабатывания: 50%%, %s)", + text = "(Вероятность срабатывания: 50%%. %s.)", cooldown = 10, pos = 2, }, ["34427"] = { -- Blackened Naaru Sliver - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34470"] = { -- Timbal's Focusing Crystal - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 15, pos = 1, }, ["34472"] = { -- Shard of Contempt - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["34473"] = { -- Commendation of Kael'thas - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 1, }, ["37064"] = { -- Vestige of Haldor - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37111"] = { -- Soul Preserver - text = "(Вероятность срабатывания: 2%%)", + text = "(Вероятность срабатывания: 2%%.)", cooldown = 0, pos = 2, }, ["37220"] = { -- Essence of Gossamer - text = "(Вероятность срабатывания: 5%%, %s)", + text = "(Вероятность срабатывания: 5%%. %s.)", cooldown = 50, pos = 1, }, ["37264"] = { -- Pendulum of Telluric Currents - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37390"] = { -- Meteorite Whetstone - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["37559"] = { -- Serrah's Star - text = "(Вероятность срабатывания: 45%%, %s)", + text = "(Вероятность срабатывания: 45%%. %s.)", cooldown = 45, pos = 2, }, ["37657"] = { -- Spark of Life - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["37660"] = { -- Forge Ember - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["37835"] = { -- Je'Tze's Bell - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 1, }, ["38071"] = { -- Valonforth's Remembrance - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["38072"] = { -- Thunder Capacitor - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 1, }, ["38212"] = { -- Death Knight's Anguish - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["38358"] = { -- Arcane Revitalizer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38359"] = { -- Goblin Repetition Reducer - text = "(%s)", + text = "(%s.)", cooldown = 10, pos = 2, }, ["38674"] = { -- Soul Harvester's Charm - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["38675"] = { -- Signet of the Dark Brotherhood - text = "(Вероятность срабатывания: 30%%, %s)", + text = "(Вероятность срабатывания: 30%%. %s.)", cooldown = 45, pos = 2, }, ["39229"] = { -- Embrace of the Spider - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["39889"] = { -- Horn of Argent Fury - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 1, }, ["40255"] = { -- Dying Curse - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40256"] = { -- Grim Toll - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40258"] = { -- Forethought Talisman - text = "(Вероятность срабатывания: 20%%, %s)", + text = "(Вероятность срабатывания: 20%%. %s.)", cooldown = 45, pos = 2, }, ["40371"] = { -- Bandit's Insignia - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["40373"] = { -- Extract of Necromantic Power - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 15, pos = 2, }, ["40382"] = { -- Soul of the Dead - text = "(Вероятность срабатывания: 25%%, %s)", + text = "(Вероятность срабатывания: 25%%. %s.)", cooldown = 45, pos = 2, }, ["40682"] = { -- Sundial of the Exiled - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40684"] = { -- Mirror of Truth - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["40685"] = { -- The Egg of Mortal Essence - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["40767"] = { -- Sonic Booster - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 50, pos = 1, }, ["40865"] = { -- Noise Machine - text = "(Вероятность срабатывания: 50%%, %s)", + text = "(Вероятность срабатывания: 50%%. %s.)", cooldown = 50, pos = 2, }, ["42987"] = { -- Darkmoon Card: Greatness - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 1, }, ["42989"] = { -- Darkmoon Card: Berserker! - text = "(Вероятность срабатывания: 50%%)", + text = "(Вероятность срабатывания: 50%%.)", cooldown = 0, pos = 2, }, ["42990"] = { -- Darkmoon Card: Death - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43573"] = { -- Tears of Bitter Anguish - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["43829"] = { -- Crusader's Locket - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["43838"] = { -- Chuchu's Tiny Box of Horrors - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["44253"] = { -- Darkmoon Card: Greatness - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44254"] = { -- Darkmoon Card: Greatness - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44255"] = { -- Darkmoon Card: Greatness - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 1, }, ["44912"] = { -- Flow of Knowledge - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["44914"] = { -- Anvil of Titans - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45131"] = { -- Jouster's Fury - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45286"] = { -- Pyrite Infuser - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45490"] = { -- Pandora's Plea - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 1, }, ["45507"] = { -- The General's Heart - text = "(Вероятность срабатывания: 5%%, %s)", + text = "(Вероятность срабатывания: 5%%. %s.)", cooldown = 50, pos = 2, }, ["45518"] = { -- Flare of the Heavens - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45522"] = { -- Blood of the Old God - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45535"] = { -- Show of Faith - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45609"] = { -- Comet's Trail - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["45866"] = { -- Elemental Focus Stone - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["45929"] = { -- Sif's Remembrance - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["45931"] = { -- Mjolnir Runestone - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["46038"] = { -- Dark Matter - text = "(Вероятность срабатывания: 15%%, %s)", + text = "(Вероятность срабатывания: 15%%. %s.)", cooldown = 45, pos = 2, }, ["47115"] = { -- Death's Verdict - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47131"] = { -- Death's Verdict - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47182"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47188"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47213"] = { -- Abyssal Rune - text = "(Вероятность срабатывания: 25%%, %s)", + text = "(Вероятность срабатывания: 25%%. %s.)", cooldown = 45, pos = 2, }, ["47214"] = { -- Banner of Victory - text = "(Вероятность срабатывания: 20%%, %s)", + text = "(Вероятность срабатывания: 20%%. %s.)", cooldown = 50, pos = 2, }, ["47215"] = { -- Tears of the Vanquished - text = "(Вероятность срабатывания: 25%%, %s)", + text = "(Вероятность срабатывания: 25%%. %s.)", cooldown = 45, pos = 1, }, ["47216"] = { -- The Black Heart - text = "(Вероятность срабатывания: 25%%, %s)", + text = "(Вероятность срабатывания: 25%%. %s.)", cooldown = 50, pos = 1, }, ["47303"] = { -- Death's Choice - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47316"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["47464"] = { -- Death's Choice - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 2, }, ["47477"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s.)", cooldown = 2, pos = 2, }, ["49074"] = { -- Coren's Chromium Coaster - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["49076"] = { -- Mithril Pocketwatch - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49078"] = { -- Ancient Pickled Egg - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["49310"] = { -- Purified Shard of the Scale - text = "(Вероятность срабатывания: 25%%, %s)", + text = "(Вероятность срабатывания: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49463"] = { -- Purified Shard of the Flame - text = "(Вероятность срабатывания: 25%%, %s)", + text = "(Вероятность срабатывания: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49464"] = { -- Shiny Shard of the Flame - text = "(Вероятность срабатывания: 25%%, %s)", + text = "(Вероятность срабатывания: 25%%. %s.)", cooldown = 50, pos = 3, }, ["49488"] = { -- Shiny Shard of the Scale - text = "(Вероятность срабатывания: 25%%, %s)", + text = "(Вероятность срабатывания: 25%%. %s.)", cooldown = 50, pos = 3, }, ["50198"] = { -- Needle-Encrusted Scorpion - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50341"] = { -- Unidentifiable Organ - text = "(Вероятность срабатывания: 60%%)", + text = "(Вероятность срабатывания: 60%%.)", cooldown = 0, pos = 1, }, ["50342"] = { -- Whispering Fanged Skull - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50343"] = { -- Whispering Fanged Skull - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 2, }, ["50344"] = { -- Unidentifiable Organ - text = "(Вероятность срабатывания: 60%%)", + text = "(Вероятность срабатывания: 60%%.)", cooldown = 0, pos = 1, }, ["50348"] = { -- Dislodged Foreign Object - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50349"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50352"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s.)", cooldown = 30, pos = 2, }, ["50353"] = { -- Dislodged Foreign Object - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 45, pos = 2, }, ["50358"] = { -- Purified Lunar Dust - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["50359"] = { -- Althor's Abacus - text = "(Вероятность срабатывания: 30%%, %s)", + text = "(Вероятность срабатывания: 30%%. %s.)", cooldown = 45, pos = 2, }, ["50360"] = { -- Phylactery of the Nameless Lich - text = "(Вероятность срабатывания: 30%%, %s)", + text = "(Вероятность срабатывания: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50362"] = { -- Deathbringer's Will - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50363"] = { -- Deathbringer's Will - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 105, pos = 2, }, ["50365"] = { -- Phylactery of the Nameless Lich - text = "(Вероятность срабатывания: 30%%, %s)", + text = "(Вероятность срабатывания: 30%%. %s.)", cooldown = 100, pos = 2, }, ["50366"] = { -- Althor's Abacus - text = "(Вероятность срабатывания: 30%%, %s)", + text = "(Вероятность срабатывания: 30%%. %s.)", cooldown = 45, pos = 2, }, ["54569"] = { -- Sharpened Twilight Scale - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54571"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, ["54572"] = { -- Charred Twilight Scale - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54588"] = { -- Charred Twilight Scale - text = "(Вероятность срабатывания: 10%%, %s)", + text = "(Вероятность срабатывания: 10%%. %s.)", cooldown = 50, pos = 2, }, ["54590"] = { -- Sharpened Twilight Scale - text = "(Вероятность срабатывания: 35%%, %s)", + text = "(Вероятность срабатывания: 35%%. %s.)", cooldown = 45, pos = 2, }, ["54591"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s.)", cooldown = 45, pos = 1, }, }, ["zhCN"] = { ["1490"] = { -- Guardian Talisman - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 1, }, ["11302"] = { -- Uther's Strength - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 1, }, ["11810"] = { -- Force of Will - text = "(特效触发几率: 1%%)", + text = "(特效触发几率: 1%%。)", cooldown = 0, pos = 1, }, ["11815"] = { -- Hand of Justice - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 1, }, ["14557"] = { -- The Lion Horn of Stormwind - text = "(特效触发几率: 1%%)", + text = "(特效触发几率: 1%%。)", cooldown = 0, pos = 1, }, ["17774"] = { -- Mark of the Chosen - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 1, }, ["19288"] = { -- Darkmoon Card: Blue Dragon - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 1, }, ["27683"] = { -- Quagmirran's Eye - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["27896"] = { -- Alembic of Infernal Power - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 2, }, ["27922"] = { -- Mark of Defiance - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 17, pos = 2, }, ["27924"] = { -- Mark of Defiance - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 17, pos = 2, }, ["27926"] = { -- Mark of Vindication - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 25, pos = 2, }, ["27927"] = { -- Mark of Vindication - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 25, pos = 2, }, ["28034"] = { -- Hourglass of the Unraveller - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["28108"] = { -- Power Infused Mushroom - text = "(%s)", + text = "(%s。)", cooldown = 10, pos = 1, }, ["28109"] = { -- Essence Infused Mushroom - text = "(%s)", + text = "(%s。)", cooldown = 10, pos = 1, }, ["28190"] = { -- Scarab of the Infinite Cycle - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["28418"] = { -- Shiffar's Nexus-Horn - text = "(特效触发几率: 20%%, %s)", + text = "(特效触发几率: 20%%。 %s。)", cooldown = 45, pos = 2, }, ["28785"] = { -- The Lightning Capacitor - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 1, }, ["28823"] = { -- Eye of Gruul - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 2, }, ["28830"] = { -- Dragonspine Trophy - text = "(%s)", + text = "(%s。)", cooldown = 20, pos = 2, }, ["30447"] = { -- Tome of Fiery Redemption - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 1, }, ["30450"] = { -- Warp-Spring Coil - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 30, pos = 2, }, ["30619"] = { -- Fel Reaver's Piston - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 15, pos = 1, }, ["30626"] = { -- Sextant of Unstable Currents - text = "(特效触发几率: 20%%, %s)", + text = "(特效触发几率: 20%%。 %s。)", cooldown = 45, pos = 2, }, ["30627"] = { -- Tsunami Talisman - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 3, }, ["30663"] = { -- Fathom-Brooch of the Tidewalker - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 40, pos = 1, }, ["30664"] = { -- Living Root of the Wildheart - text = "(特效触发几率: 3%%)", + text = "(特效触发几率: 3%%。)", cooldown = 0, pos = 1, }, ["31858"] = { -- Darkmoon Card: Vengeance - text = "(特效触发几率: 10%%)", + text = "(特效触发几率: 10%%。)", cooldown = 0, pos = 1, }, ["32485"] = { -- Ashtongue Talisman of Valor - text = "(特效触发几率: 25%%)", + text = "(特效触发几率: 25%%。)", cooldown = 0, pos = 1, }, ["32487"] = { -- Ashtongue Talisman of Swiftness - text = "(特效触发几率: 15%%)", + text = "(特效触发几率: 15%%。)", cooldown = 0, pos = 1, }, ["32488"] = { -- Ashtongue Talisman of Insight - text = "(特效触发几率: 50%%)", + text = "(特效触发几率: 50%%。)", cooldown = 0, pos = 1, }, ["32490"] = { -- Ashtongue Talisman of Acumen - text = "(特效触发几率: 10%%)", + text = "(特效触发几率: 10%%。)", cooldown = 0, pos = 1, }, ["32493"] = { -- Ashtongue Talisman of Shadows - text = "(特效触发几率: 20%%)", + text = "(特效触发几率: 20%%。)", cooldown = 0, pos = 1, }, ["32496"] = { -- Memento of Tyrande - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["32770"] = { -- Skyguard Silver Cross - text = "(特效触发几率: 50%%, %s)", + text = "(特效触发几率: 50%%。 %s。)", cooldown = 10, pos = 2, }, ["32771"] = { -- Airman's Ribbon of Gallantry - text = "(特效触发几率: 50%%, %s)", + text = "(特效触发几率: 50%%。 %s。)", cooldown = 10, pos = 2, }, ["34427"] = { -- Blackened Naaru Sliver - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["34470"] = { -- Timbal's Focusing Crystal - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 15, pos = 1, }, ["34472"] = { -- Shard of Contempt - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["34473"] = { -- Commendation of Kael'thas - text = "(%s)", + text = "(%s。)", cooldown = 30, pos = 1, }, ["37064"] = { -- Vestige of Haldor - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["37111"] = { -- Soul Preserver - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 2, }, ["37220"] = { -- Essence of Gossamer - text = "(特效触发几率: 5%%, %s)", + text = "(特效触发几率: 5%%。 %s。)", cooldown = 50, pos = 1, }, ["37264"] = { -- Pendulum of Telluric Currents - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["37390"] = { -- Meteorite Whetstone - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["37559"] = { -- Serrah's Star - text = "(特效触发几率: 45%%, %s)", + text = "(特效触发几率: 45%%。 %s。)", cooldown = 45, pos = 2, }, ["37657"] = { -- Spark of Life - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["37660"] = { -- Forge Ember - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["37835"] = { -- Je'Tze's Bell - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 1, }, ["38071"] = { -- Valonforth's Remembrance - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["38072"] = { -- Thunder Capacitor - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 1, }, ["38212"] = { -- Death Knight's Anguish - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["38358"] = { -- Arcane Revitalizer - text = "(%s)", + text = "(%s。)", cooldown = 10, pos = 2, }, ["38359"] = { -- Goblin Repetition Reducer - text = "(%s)", + text = "(%s。)", cooldown = 10, pos = 2, }, ["38674"] = { -- Soul Harvester's Charm - text = "(%s)", + text = "(%s。)", cooldown = 30, pos = 2, }, ["38675"] = { -- Signet of the Dark Brotherhood - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 45, pos = 2, }, ["39229"] = { -- Embrace of the Spider - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["39889"] = { -- Horn of Argent Fury - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 1, }, ["40255"] = { -- Dying Curse - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["40256"] = { -- Grim Toll - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["40258"] = { -- Forethought Talisman - text = "(特效触发几率: 20%%, %s)", + text = "(特效触发几率: 20%%。 %s。)", cooldown = 45, pos = 2, }, ["40371"] = { -- Bandit's Insignia - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["40373"] = { -- Extract of Necromantic Power - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 15, pos = 2, }, ["40382"] = { -- Soul of the Dead - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 45, pos = 2, }, ["40682"] = { -- Sundial of the Exiled - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["40684"] = { -- Mirror of Truth - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["40685"] = { -- The Egg of Mortal Essence - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["40767"] = { -- Sonic Booster - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 50, pos = 1, }, ["40865"] = { -- Noise Machine - text = "(特效触发几率: 50%%, %s)", + text = "(特效触发几率: 50%%。 %s。)", cooldown = 50, pos = 2, }, ["42987"] = { -- Darkmoon Card: Greatness - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 1, }, ["42989"] = { -- Darkmoon Card: Berserker! - text = "(特效触发几率: 50%%)", + text = "(特效触发几率: 50%%。)", cooldown = 0, pos = 2, }, ["42990"] = { -- Darkmoon Card: Death - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["43573"] = { -- Tears of Bitter Anguish - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["43829"] = { -- Crusader's Locket - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["43838"] = { -- Chuchu's Tiny Box of Horrors - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["44253"] = { -- Darkmoon Card: Greatness - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 1, }, ["44254"] = { -- Darkmoon Card: Greatness - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 1, }, ["44255"] = { -- Darkmoon Card: Greatness - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 1, }, ["44912"] = { -- Flow of Knowledge - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["44914"] = { -- Anvil of Titans - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45131"] = { -- Jouster's Fury - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45286"] = { -- Pyrite Infuser - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45490"] = { -- Pandora's Plea - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 1, }, ["45507"] = { -- The General's Heart - text = "(特效触发几率: 5%%, %s)", + text = "(特效触发几率: 5%%。 %s。)", cooldown = 50, pos = 2, }, ["45518"] = { -- Flare of the Heavens - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["45522"] = { -- Blood of the Old God - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45535"] = { -- Show of Faith - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45609"] = { -- Comet's Trail - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["45866"] = { -- Elemental Focus Stone - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["45929"] = { -- Sif's Remembrance - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45931"] = { -- Mjolnir Runestone - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["46038"] = { -- Dark Matter - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["47115"] = { -- Death's Verdict - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["47131"] = { -- Death's Verdict - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["47182"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 2, }, ["47188"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 2, }, ["47213"] = { -- Abyssal Rune - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 45, pos = 2, }, ["47214"] = { -- Banner of Victory - text = "(特效触发几率: 20%%, %s)", + text = "(特效触发几率: 20%%。 %s。)", cooldown = 50, pos = 2, }, ["47215"] = { -- Tears of the Vanquished - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 45, pos = 1, }, ["47216"] = { -- The Black Heart - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 1, }, ["47303"] = { -- Death's Choice - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["47316"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 2, }, ["47464"] = { -- Death's Choice - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["47477"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 2, }, ["49074"] = { -- Coren's Chromium Coaster - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["49076"] = { -- Mithril Pocketwatch - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["49078"] = { -- Ancient Pickled Egg - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["49310"] = { -- Purified Shard of the Scale - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 3, }, ["49463"] = { -- Purified Shard of the Flame - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 3, }, ["49464"] = { -- Shiny Shard of the Flame - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 3, }, ["49488"] = { -- Shiny Shard of the Scale - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 3, }, ["50198"] = { -- Needle-Encrusted Scorpion - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["50341"] = { -- Unidentifiable Organ - text = "(特效触发几率: 60%%)", + text = "(特效触发几率: 60%%。)", cooldown = 0, pos = 1, }, ["50342"] = { -- Whispering Fanged Skull - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["50343"] = { -- Whispering Fanged Skull - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["50344"] = { -- Unidentifiable Organ - text = "(特效触发几率: 60%%)", + text = "(特效触发几率: 60%%。)", cooldown = 0, pos = 1, }, ["50348"] = { -- Dislodged Foreign Object - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["50349"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s。)", cooldown = 30, pos = 2, }, ["50352"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s。)", cooldown = 30, pos = 2, }, ["50353"] = { -- Dislodged Foreign Object - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["50358"] = { -- Purified Lunar Dust - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["50359"] = { -- Althor's Abacus - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 45, pos = 2, }, ["50360"] = { -- Phylactery of the Nameless Lich - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 100, pos = 2, }, ["50362"] = { -- Deathbringer's Will - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 105, pos = 2, }, ["50363"] = { -- Deathbringer's Will - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 105, pos = 2, }, ["50365"] = { -- Phylactery of the Nameless Lich - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 100, pos = 2, }, ["50366"] = { -- Althor's Abacus - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 45, pos = 2, }, ["54569"] = { -- Sharpened Twilight Scale - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["54571"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s。)", cooldown = 45, pos = 1, }, ["54572"] = { -- Charred Twilight Scale - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["54588"] = { -- Charred Twilight Scale - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["54590"] = { -- Sharpened Twilight Scale - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["54591"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s。)", cooldown = 45, pos = 1, }, }, ["zhTW"] = { ["1490"] = { -- Guardian Talisman - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 1, }, ["11302"] = { -- Uther's Strength - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 1, }, ["11810"] = { -- Force of Will - text = "(特效触发几率: 1%%)", + text = "(特效触发几率: 1%%。)", cooldown = 0, pos = 1, }, ["11815"] = { -- Hand of Justice - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 1, }, ["14557"] = { -- The Lion Horn of Stormwind - text = "(特效触发几率: 1%%)", + text = "(特效触发几率: 1%%。)", cooldown = 0, pos = 1, }, ["17774"] = { -- Mark of the Chosen - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 1, }, ["19288"] = { -- Darkmoon Card: Blue Dragon - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 1, }, ["27683"] = { -- Quagmirran's Eye - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["27896"] = { -- Alembic of Infernal Power - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 2, }, ["27922"] = { -- Mark of Defiance - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 17, pos = 2, }, ["27924"] = { -- Mark of Defiance - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 17, pos = 2, }, ["27926"] = { -- Mark of Vindication - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 25, pos = 2, }, ["27927"] = { -- Mark of Vindication - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 25, pos = 2, }, ["28034"] = { -- Hourglass of the Unraveller - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["28108"] = { -- Power Infused Mushroom - text = "(%s)", + text = "(%s。)", cooldown = 10, pos = 1, }, ["28109"] = { -- Essence Infused Mushroom - text = "(%s)", + text = "(%s。)", cooldown = 10, pos = 1, }, ["28190"] = { -- Scarab of the Infinite Cycle - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["28418"] = { -- Shiffar's Nexus-Horn - text = "(特效触发几率: 20%%, %s)", + text = "(特效触发几率: 20%%。 %s。)", cooldown = 45, pos = 2, }, ["28785"] = { -- The Lightning Capacitor - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 1, }, ["28823"] = { -- Eye of Gruul - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 2, }, ["28830"] = { -- Dragonspine Trophy - text = "(%s)", + text = "(%s。)", cooldown = 20, pos = 2, }, ["30447"] = { -- Tome of Fiery Redemption - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 1, }, ["30450"] = { -- Warp-Spring Coil - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 30, pos = 2, }, ["30619"] = { -- Fel Reaver's Piston - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 15, pos = 1, }, ["30626"] = { -- Sextant of Unstable Currents - text = "(特效触发几率: 20%%, %s)", + text = "(特效触发几率: 20%%。 %s。)", cooldown = 45, pos = 2, }, ["30627"] = { -- Tsunami Talisman - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 3, }, ["30663"] = { -- Fathom-Brooch of the Tidewalker - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 40, pos = 1, }, ["30664"] = { -- Living Root of the Wildheart - text = "(特效触发几率: 3%%)", + text = "(特效触发几率: 3%%。)", cooldown = 0, pos = 1, }, ["31858"] = { -- Darkmoon Card: Vengeance - text = "(特效触发几率: 10%%)", + text = "(特效触发几率: 10%%。)", cooldown = 0, pos = 1, }, ["32485"] = { -- Ashtongue Talisman of Valor - text = "(特效触发几率: 25%%)", + text = "(特效触发几率: 25%%。)", cooldown = 0, pos = 1, }, ["32487"] = { -- Ashtongue Talisman of Swiftness - text = "(特效触发几率: 15%%)", + text = "(特效触发几率: 15%%。)", cooldown = 0, pos = 1, }, ["32488"] = { -- Ashtongue Talisman of Insight - text = "(特效触发几率: 50%%)", + text = "(特效触发几率: 50%%。)", cooldown = 0, pos = 1, }, ["32490"] = { -- Ashtongue Talisman of Acumen - text = "(特效触发几率: 10%%)", + text = "(特效触发几率: 10%%。)", cooldown = 0, pos = 1, }, ["32493"] = { -- Ashtongue Talisman of Shadows - text = "(特效触发几率: 20%%)", + text = "(特效触发几率: 20%%。)", cooldown = 0, pos = 1, }, ["32496"] = { -- Memento of Tyrande - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["32770"] = { -- Skyguard Silver Cross - text = "(特效触发几率: 50%%, %s)", + text = "(特效触发几率: 50%%。 %s。)", cooldown = 10, pos = 2, }, ["32771"] = { -- Airman's Ribbon of Gallantry - text = "(特效触发几率: 50%%, %s)", + text = "(特效触发几率: 50%%。 %s。)", cooldown = 10, pos = 2, }, ["34427"] = { -- Blackened Naaru Sliver - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["34470"] = { -- Timbal's Focusing Crystal - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 15, pos = 1, }, ["34472"] = { -- Shard of Contempt - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["34473"] = { -- Commendation of Kael'thas - text = "(%s)", + text = "(%s。)", cooldown = 30, pos = 1, }, ["37064"] = { -- Vestige of Haldor - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["37111"] = { -- Soul Preserver - text = "(特效触发几率: 2%%)", + text = "(特效触发几率: 2%%。)", cooldown = 0, pos = 2, }, ["37220"] = { -- Essence of Gossamer - text = "(特效触发几率: 5%%, %s)", + text = "(特效触发几率: 5%%。 %s。)", cooldown = 50, pos = 1, }, ["37264"] = { -- Pendulum of Telluric Currents - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["37390"] = { -- Meteorite Whetstone - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["37559"] = { -- Serrah's Star - text = "(特效触发几率: 45%%, %s)", + text = "(特效触发几率: 45%%。 %s。)", cooldown = 45, pos = 2, }, ["37657"] = { -- Spark of Life - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["37660"] = { -- Forge Ember - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["37835"] = { -- Je'Tze's Bell - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 1, }, ["38071"] = { -- Valonforth's Remembrance - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["38072"] = { -- Thunder Capacitor - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 1, }, ["38212"] = { -- Death Knight's Anguish - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["38358"] = { -- Arcane Revitalizer - text = "(%s)", + text = "(%s。)", cooldown = 10, pos = 2, }, ["38359"] = { -- Goblin Repetition Reducer - text = "(%s)", + text = "(%s。)", cooldown = 10, pos = 2, }, ["38674"] = { -- Soul Harvester's Charm - text = "(%s)", + text = "(%s。)", cooldown = 30, pos = 2, }, ["38675"] = { -- Signet of the Dark Brotherhood - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 45, pos = 2, }, ["39229"] = { -- Embrace of the Spider - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["39889"] = { -- Horn of Argent Fury - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 1, }, ["40255"] = { -- Dying Curse - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["40256"] = { -- Grim Toll - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["40258"] = { -- Forethought Talisman - text = "(特效触发几率: 20%%, %s)", + text = "(特效触发几率: 20%%。 %s。)", cooldown = 45, pos = 2, }, ["40371"] = { -- Bandit's Insignia - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["40373"] = { -- Extract of Necromantic Power - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 15, pos = 2, }, ["40382"] = { -- Soul of the Dead - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 45, pos = 2, }, ["40682"] = { -- Sundial of the Exiled - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["40684"] = { -- Mirror of Truth - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["40685"] = { -- The Egg of Mortal Essence - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["40767"] = { -- Sonic Booster - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 50, pos = 1, }, ["40865"] = { -- Noise Machine - text = "(特效触发几率: 50%%, %s)", + text = "(特效触发几率: 50%%。 %s。)", cooldown = 50, pos = 2, }, ["42987"] = { -- Darkmoon Card: Greatness - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 1, }, ["42989"] = { -- Darkmoon Card: Berserker! - text = "(特效触发几率: 50%%)", + text = "(特效触发几率: 50%%。)", cooldown = 0, pos = 2, }, ["42990"] = { -- Darkmoon Card: Death - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["43573"] = { -- Tears of Bitter Anguish - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["43829"] = { -- Crusader's Locket - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["43838"] = { -- Chuchu's Tiny Box of Horrors - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["44253"] = { -- Darkmoon Card: Greatness - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 1, }, ["44254"] = { -- Darkmoon Card: Greatness - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 1, }, ["44255"] = { -- Darkmoon Card: Greatness - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 1, }, ["44912"] = { -- Flow of Knowledge - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["44914"] = { -- Anvil of Titans - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45131"] = { -- Jouster's Fury - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45286"] = { -- Pyrite Infuser - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45490"] = { -- Pandora's Plea - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 1, }, ["45507"] = { -- The General's Heart - text = "(特效触发几率: 5%%, %s)", + text = "(特效触发几率: 5%%。 %s。)", cooldown = 50, pos = 2, }, ["45518"] = { -- Flare of the Heavens - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["45522"] = { -- Blood of the Old God - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45535"] = { -- Show of Faith - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45609"] = { -- Comet's Trail - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["45866"] = { -- Elemental Focus Stone - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["45929"] = { -- Sif's Remembrance - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["45931"] = { -- Mjolnir Runestone - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["46038"] = { -- Dark Matter - text = "(特效触发几率: 15%%, %s)", + text = "(特效触发几率: 15%%。 %s。)", cooldown = 45, pos = 2, }, ["47115"] = { -- Death's Verdict - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["47131"] = { -- Death's Verdict - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["47182"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 2, }, ["47188"] = { -- Reign of the Unliving - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 2, }, ["47213"] = { -- Abyssal Rune - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 45, pos = 2, }, ["47214"] = { -- Banner of Victory - text = "(特效触发几率: 20%%, %s)", + text = "(特效触发几率: 20%%。 %s。)", cooldown = 50, pos = 2, }, ["47215"] = { -- Tears of the Vanquished - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 45, pos = 1, }, ["47216"] = { -- The Black Heart - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 1, }, ["47303"] = { -- Death's Choice - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["47316"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 2, }, ["47464"] = { -- Death's Choice - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["47477"] = { -- Reign of the Dead - text = "(%s)", + text = "(%s。)", cooldown = 2, pos = 2, }, ["49074"] = { -- Coren's Chromium Coaster - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["49076"] = { -- Mithril Pocketwatch - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["49078"] = { -- Ancient Pickled Egg - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["49310"] = { -- Purified Shard of the Scale - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 3, }, ["49463"] = { -- Purified Shard of the Flame - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 3, }, ["49464"] = { -- Shiny Shard of the Flame - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 3, }, ["49488"] = { -- Shiny Shard of the Scale - text = "(特效触发几率: 25%%, %s)", + text = "(特效触发几率: 25%%。 %s。)", cooldown = 50, pos = 3, }, ["50198"] = { -- Needle-Encrusted Scorpion - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["50341"] = { -- Unidentifiable Organ - text = "(特效触发几率: 60%%)", + text = "(特效触发几率: 60%%。)", cooldown = 0, pos = 1, }, ["50342"] = { -- Whispering Fanged Skull - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["50343"] = { -- Whispering Fanged Skull - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["50344"] = { -- Unidentifiable Organ - text = "(特效触发几率: 60%%)", + text = "(特效触发几率: 60%%。)", cooldown = 0, pos = 1, }, ["50348"] = { -- Dislodged Foreign Object - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["50349"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s。)", cooldown = 30, pos = 2, }, ["50352"] = { -- Corpse Tongue Coin - text = "(%s)", + text = "(%s。)", cooldown = 30, pos = 2, }, ["50353"] = { -- Dislodged Foreign Object - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 45, pos = 2, }, ["50358"] = { -- Purified Lunar Dust - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["50359"] = { -- Althor's Abacus - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 45, pos = 2, }, ["50360"] = { -- Phylactery of the Nameless Lich - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 100, pos = 2, }, ["50362"] = { -- Deathbringer's Will - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 105, pos = 2, }, ["50363"] = { -- Deathbringer's Will - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 105, pos = 2, }, ["50365"] = { -- Phylactery of the Nameless Lich - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 100, pos = 2, }, ["50366"] = { -- Althor's Abacus - text = "(特效触发几率: 30%%, %s)", + text = "(特效触发几率: 30%%。 %s。)", cooldown = 45, pos = 2, }, ["54569"] = { -- Sharpened Twilight Scale - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["54571"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s。)", cooldown = 45, pos = 1, }, ["54572"] = { -- Charred Twilight Scale - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["54588"] = { -- Charred Twilight Scale - text = "(特效触发几率: 10%%, %s)", + text = "(特效触发几率: 10%%。 %s。)", cooldown = 50, pos = 2, }, ["54590"] = { -- Sharpened Twilight Scale - text = "(特效触发几率: 35%%, %s)", + text = "(特效触发几率: 35%%。 %s。)", cooldown = 45, pos = 2, }, ["54591"] = { -- Petrified Twilight Scale - text = "(%s)", + text = "(%s。)", cooldown = 45, pos = 1, }, diff --git a/Modules/General/MoversPlus.lua b/Modules/General/MoversPlus.lua index d76cf4b..08ea03a 100644 --- a/Modules/General/MoversPlus.lua +++ b/Modules/General/MoversPlus.lua @@ -74,7 +74,7 @@ function mod:LoadConfig() enabled = { type = "toggle", name = core.pluginColor..L["Enable"], - desc = L["Adds anchoring options to movers' nudges."], + desc = L["Adds anchoring options to the movers' nudges."], }, }, }, @@ -273,7 +273,7 @@ end function mod:Toggle(enable) - if enable then + if not core.reload and enable then for _, func in pairs({'UpdateNudgeFrame', 'NudgeMover', 'ResetMovers'}) do if not self:IsHooked(E, func) then self:SecureHook(E, func) end end diff --git a/Modules/General/QuestBar.lua b/Modules/General/QuestBar.lua index 56e46f5..3a5c2f9 100644 --- a/Modules/General/QuestBar.lua +++ b/Modules/General/QuestBar.lua @@ -69,7 +69,7 @@ function mod:LoadConfig(db) type = "toggle", name = core.pluginColor..L["Enable"], desc = L["A new action bar that collects usable quest items from your bag.\n\nDue to state actions limit, this module overrides bar10 created by ElvUI Extra Action Bars."], - set = function(info, value) db[info[#info]] = value mod:Toggle(value) end, + set = function(info, value) db[info[#info]] = value self:Toggle(db) end, }, }, }, @@ -85,7 +85,7 @@ function mod:LoadConfig(db) type = "toggle", width = "full", name = L["Backdrop"], - desc = L["Toggles the display of the actionbars backdrop."], + desc = L["Toggles the display of the actionbar's backdrop."], }, showGrid = { order = 2, @@ -104,13 +104,13 @@ function mod:LoadConfig(db) order = 3, type = "toggle", name = L["Mouse Over"], - desc = L["The frame won't show unless you mouse over it."], + desc = L["The frame will not be displayed unless hovered over."], }, inheritGlobalFade = { order = 4, type = "toggle", name = L["Inherit Global Fade"], - desc = L["Inherit the global fade, mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."], + desc = L["Inherit the global fade; mousing over, targetting, setting focus, losing health, entering combat will set the remove transparency. Otherwise it will use the transparency level in the general actionbar settings for global fade alpha."], }, point = { order = 5, @@ -130,7 +130,7 @@ function mod:LoadConfig(db) order = 7, type = "range", name = L["Buttons"], - desc = L["The amount of buttons to display."], + desc = L["The number of buttons to display."], hidden = function() return true end, @@ -140,7 +140,7 @@ function mod:LoadConfig(db) order = 8, type = "range", name = L["Buttons Per Row"], - desc = L["The amount of buttons to display per row."], + desc = L["The number of buttons to display per row."], hidden = function() return true end, @@ -157,28 +157,28 @@ function mod:LoadConfig(db) order = 10, type = "range", name = L["Button Spacing"], - desc = L["The spacing between buttons."], + desc = L["Spacing between the buttons."], min = -1, max = 10, step = 1, }, backdropSpacing = { order = 11, type = "range", name = L["Backdrop Spacing"], - desc = L["The spacing between the backdrop and the buttons."], + desc = L["Spacing between the backdrop and the buttons."], min = 0, max = 10, step = 1, }, heightMult = { order = 12, type = "range", name = L["Height Multiplier"], - desc = L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."], + desc = L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."], min = 1, max = 5, step = 1, }, widthMult = { order = 13, type = "range", name = L["Width Multiplier"], - desc = L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."], + desc = L["Multiply the backdrop's height or width by this value. This is useful if you wish to have more than one bar behind a backdrop."], min = 1, max = 5, step = 1, }, alpha = { @@ -193,7 +193,7 @@ function mod:LoadConfig(db) order = 15, type = "input", name = L["Visibility State"], - desc = L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] showhide'"], + desc = L["This works like a macro; you can run different conditions to show or hide the action bar.\n Example: '[combat] showhide'"], width = "double", multiline = true, set = function(info, value) @@ -293,7 +293,7 @@ end function mod:Toggle(db) - if db.enabled then + if not core.reload and db.enabled then local bar = AB.handledBars["bar"..modName] if bar then bar.db.enabled = true @@ -355,4 +355,4 @@ function mod:InitializeCallback() mod:Toggle(db) end -core.modules[modName] = mod.InitializeCallback +core.modules[modName] = mod.InitializeCallback \ No newline at end of file diff --git a/Modules/Nameplates/Auras.lua b/Modules/Nameplates/Auras.lua index 5cebc71..dd4dfb8 100644 --- a/Modules/Nameplates/Auras.lua +++ b/Modules/Nameplates/Auras.lua @@ -24,10 +24,10 @@ local funcMap = { local function updateVisiblePlates() for plate in pairs(NP.VisiblePlates) do - for typelow, type in pairs({buffs = 'Buffs', debuffs = 'Debuffs'}) do - local db = NP.db.units[plate.UnitType][typelow] + for auraType, AuraType in pairs({buffs = 'Buffs', debuffs = 'Debuffs'}) do + local db = NP.db.units[plate.UnitType][auraType] if db.enable then - local frame = plate[type] + local frame = plate[AuraType] for _, button in ipairs(frame) do button:SetAlpha(1) if button.bg:GetAlpha() == 0 then @@ -95,18 +95,18 @@ function mod:LoadConfig() local db = E.db.Extras.nameplates[modName] local function selectedType() return db.Highlights.selectedType or "FRIENDLY" end local function selectedSpellorFilter() return db.Highlights.types[selectedType()].selected or "GLOBAL" end - local function getHighlightSettings(selectedType, spellOrFilter) - local db = db.Highlights.types[selectedType] + local function getHighlightSettings(selected, spellOrFilter) + local data = db.Highlights.types[selected] if spellOrFilter == "GLOBAL" then - return db.global + return data.global elseif spellOrFilter == "CURABLE" or spellOrFilter == "STEALABLE" then - return db.special + return data.special elseif type(spellOrFilter) == 'number' then - return db.spellList[spellOrFilter].useGlobal and db.global or db.spellList[spellOrFilter] - elseif db.filterList[spellOrFilter] then - return db.filterList[spellOrFilter].useGlobal and db.global or db.filterList[spellOrFilter] + return data.spellList[spellOrFilter].useGlobal and data.global or data.spellList[spellOrFilter] + elseif data.filterList[spellOrFilter] then + return data.filterList[spellOrFilter].useGlobal and data.global or data.filterList[spellOrFilter] end - return db.global + return data.global end core.nameplates.args[modName] = { type = "group", @@ -177,7 +177,7 @@ function mod:LoadConfig() order = 2, type = "select", name = L["Add Filter"], - desc = L["Aplies highlights to all auras passing the selected filter."], + desc = L["Applies highlights to all auras passing the selected filter."], values = function() local filters = {} for filterName in pairs(E.global.unitframe.aurafilters) do @@ -208,19 +208,19 @@ function mod:LoadConfig() desc = "", func = function() local selected = selectedSpellorFilter() - local db = db.Highlights.types[selectedType()] + local data = db.Highlights.types[selectedType()] if type(selected) == 'number' then - db.spellList[selected] = nil + data.spellList[selected] = nil local _, _, icon = GetSpellInfo(selected) local link = GetSpellLink(selected) icon = gsub(icon, '\124', '\124\124') local string = '\124T' .. icon .. ':16:16\124t' .. link core:print('REMOVED', string) else - db.filterList[selected] = nil + data.filterList[selected] = nil core:print('REMOVED', selected, L[" filter removed."]) end - db.selected = "GLOBAL" + data.selected = "GLOBAL" updateVisiblePlates() end, disabled = function() return selectedSpellorFilter() == "GLOBAL" or selectedSpellorFilter() == "CURABLE" or selectedSpellorFilter() == "STEALABLE" end, @@ -272,14 +272,14 @@ function mod:LoadConfig() desc = L["If toggled, the GLOBAL Spell or Filter entry values would be used."], get = function() local selected = selectedSpellorFilter() - local db = db.Highlights.types[selectedType()] - local target = type(selected) == 'number' and db.spellList[selected] or db.filterList[selected] + local data = db.Highlights.types[selectedType()] + local target = type(selected) == 'number' and data.spellList[selected] or data.filterList[selected] return selected == 'GLOBAL' or selected == 'CURABLE' or selected == 'STEALABLE' or target.useGlobal end, set = function(_, value) local selected = selectedSpellorFilter() - local db = db.Highlights.types[selectedType()] - local target = type(selected) == 'number' and db.spellList[selected] or db.filterList[selected] + local data = db.Highlights.types[selectedType()] + local target = type(selected) == 'number' and data.spellList[selected] or data.filterList[selected] target.useGlobal = value updateVisiblePlates() end, @@ -555,16 +555,16 @@ function mod:ApplyHighlight(db, button) button.shadow:SetOutside(button, db.size, db.size) button.shadow:SetBackdrop({edgeFile = LSM:Fetch("border", "ElvUI GlowBorder"), edgeSize = E:Scale(db.size)}) button.shadow:SetBackdropBorderColor(unpack(db.shadowColor)) + button.shadow:Show() elseif button.shadow then button.shadow:Hide() - button.shadow = nil end button.highlightApplied = true end -function mod:ClearHighlights(button, isDebuff, debuffType, unstableAffliction, vampiricTouch) +function mod:ClearHighlights(mod_db, button, isDebuff, debuffType, unstableAffliction, vampiricTouch) if isDebuff then - if E.db.Extras.nameplates[modName].TypeBorders.enabled then + if mod_db.TypeBorders.enabled then NP:StyleFrameColor(button, unpack(E.media.bordercolor)) elseif (button.name and (button.name == unstableAffliction or button.name == vampiricTouch) and E.myclass ~= "WARLOCK") then NP:StyleFrameColor(button, 0.05, 0.85, 0.94) @@ -577,15 +577,18 @@ function mod:ClearHighlights(button, isDebuff, debuffType, unstableAffliction, v end if button.shadow then button.shadow:Hide() - button.shadow = nil end button.highlightApplied = false end -function mod:HandleCurableStealable(db, button, debuffType, unstableAffliction, vampiricTouch, attackable, dtype, isDebuff, name) - if (db.shadow or db.border) and (attackable or (E.myclass == "WARLOCK" or (name and (name ~= unstableAffliction and name ~= vampiricTouch)))) and dtype and find(dtype, '%S+') then +function mod:HandleCurableStealable(mod_db, db, button, debuffType, unstableAffliction, vampiricTouch, attackable, dtype, isDebuff, name) + if (db.shadow or db.border) + and (attackable + or (E.myclass == "WARLOCK" + or (name and (name ~= unstableAffliction and name ~= vampiricTouch)))) and dtype and find(dtype, '%S+') then if (attackable and isDebuff) or (not attackable and not isDebuff) - or (isDebuff and not (dispellList and dispellList[dtype])) or (not isDebuff and not purgeList) then + or (isDebuff and not (dispellList and dispellList[dtype])) + or (not isDebuff and not purgeList) then if button.highlightApplied then self:ClearHighlights(button, isDebuff, debuffType, unstableAffliction, vampiricTouch) end @@ -593,7 +596,7 @@ function mod:HandleCurableStealable(db, button, debuffType, unstableAffliction, end self:ApplyHighlight(db, button) elseif button.highlightApplied then - self:ClearHighlights(button, isDebuff, debuffType, unstableAffliction, vampiricTouch) + self:ClearHighlights(mod_db, button, isDebuff, debuffType, unstableAffliction, vampiricTouch) end end @@ -602,24 +605,27 @@ function mod:SetAura(frame, guid, index, filter, isDebuff, visible) if isAura then local position = visible + 1 local button = frame[position] or NP:Construct_AuraIcon(frame, position) - local db = E.db.Extras.nameplates[modName] + local mod_db = E.db.Extras.nameplates[modName] - if db.CooldownDisable.enabled then + if mod_db.CooldownDisable.enabled then button:SetStatusBarColor(1,1,1,0) button.bg:SetAlpha(0) end - if isDebuff and db.TypeBorders.enabled then + if isDebuff and mod_db.TypeBorders.enabled then NP:StyleFrameColor(button, unpack(E.media.bordercolor)) end local plate = frame:GetParent() - local attackable = plate.unit and UnitCanAttack('player', plate.unit) == 1 or (frame.UnitType and match(frame.UnitType, 'ENEMY')) + local parent = plate:GetParent() + local unitType = plate.UnitType + local attackable = parent.unit and UnitCanAttack('player', parent.unit) == 1 or (unitType and find(unitType, 'ENEMY')) + local db if attackable then - db = db.Highlights.types['ENEMY'] + db = mod_db.Highlights.types['ENEMY'] else - db = db.Highlights.types['FRIENDLY'] + db = mod_db.Highlights.types['FRIENDLY'] end if not db.enabled then return end @@ -631,7 +637,7 @@ function mod:SetAura(frame, guid, index, filter, isDebuff, visible) if dbSpell then local settings = (dbSpell.shadow or dbSpell.border or dbSpell.useGlobal) and (dbSpell.useGlobal and db.global or dbSpell) if not settings then - mod:HandleCurableStealable(db.special, button, debuffType, unstableAffliction, vampiricTouch, attackable, dtype, isDebuff, name) + mod:HandleCurableStealable(mod_db, db.special, button, debuffType, unstableAffliction, vampiricTouch, attackable, dtype, isDebuff, name) else mod:ApplyHighlight(settings, button) end @@ -647,11 +653,13 @@ function mod:SetAura(frame, guid, index, filter, isDebuff, visible) if checkFilters then local parent = button:GetParent() local parentType = parent.type - local db = NP.db.units[parent:GetParent().UnitType][parentType] + local db = NP.db.units[unitType][parentType] if db then local duration = button.duration local noDuration = (not duration or duration == 0) - local allowDuration = noDuration or (duration and (duration > 0) and db.filters.maxDuration == 0 or duration <= db.filters.maxDuration) and (db.filters.minDuration == 0 or duration >= db.filters.minDuration) + local allowDuration = noDuration + or (duration and (duration > 0) and db.filters.maxDuration == 0 or duration <= db.filters.maxDuration) + and (db.filters.minDuration == 0 or duration >= db.filters.minDuration) for filterName, db in pairs(tempFilterList) do if NP:CheckFilter(name, spellID, button.isPlayer, allowDuration, noDuration, filterName) then settings = db @@ -661,7 +669,7 @@ function mod:SetAura(frame, guid, index, filter, isDebuff, visible) end end if not settings then - mod:HandleCurableStealable(db.special, button, debuffType, unstableAffliction, vampiricTouch, attackable, dtype, isDebuff, name) + mod:HandleCurableStealable(mod_db, db.special, button, debuffType, unstableAffliction, vampiricTouch, attackable, dtype, isDebuff, name) elseif settings.border or settings.shadow then mod:ApplyHighlight(settings, button) elseif button.highlightApplied then @@ -679,7 +687,7 @@ function mod:Toggle(db) for setting in gmatch(settings, "%a+") do local config = db[setting] if setting == 'Highlights' and (config.types['FRIENDLY'].enabled or config.types['ENEMY'].enabled) or config.enabled then - toggles[func] = true + toggles[func] = not core.reload end end end diff --git a/Modules/Nameplates/ClassificationIcons.lua b/Modules/Nameplates/ClassificationIcons.lua index a73d7f2..95af078 100644 --- a/Modules/Nameplates/ClassificationIcons.lua +++ b/Modules/Nameplates/ClassificationIcons.lua @@ -193,7 +193,7 @@ function mod:LoadConfig() get = function() return selectedNPCsData().texture end, set = function(_, value) selectedNPCsData().texture = value NP:ConfigureAll() end, hidden = function() return selectedSubSection() ~= 'NPCs' or selectedNPCsData().keepOrigTex end, - values = function(info) + values = function() local type = db.NPCs.selectedTexList local list = type == 'CLASSIFICATION' and 'texClassificaion' or 'texGeneral' return core:GetIconList(E.db.Extras[list]) @@ -315,7 +315,7 @@ function mod:LoadConfig() desc = "", get = function() return selectedPlayersData().classes[db.Players.selectedClass].texture end, set = function(_, value) selectedPlayersData().classes[db.Players.selectedClass].texture = value NP:ConfigureAll() end, - values = function(info) + values = function() local type = db.Players.selectedTexList local list = (type == 'CLASS' and 'texClass') or (type == 'VECTOR' and 'texClassVector') @@ -575,14 +575,16 @@ function mod:Toggle(db) end end end - NP:ConfigureAll() + if not core.reload then + NP:ConfigureAll() + end end function mod:InitializeCallback() if not E.private.nameplates.enable then return end mod:LoadConfig() - mod:Toggle(E.db.Extras.nameplates[modName]) + mod:Toggle(core.reload and {NPCs = {types = {Elite = {}, Boss = {}}}, Players = {}} or E.db.Extras.nameplates[modName]) end core.modules[modName] = mod.InitializeCallback \ No newline at end of file diff --git a/Modules/Nameplates/Cooldowns.lua b/Modules/Nameplates/Cooldowns.lua index 98f66c4..e70b8a4 100644 --- a/Modules/Nameplates/Cooldowns.lua +++ b/Modules/Nameplates/Cooldowns.lua @@ -1106,14 +1106,14 @@ function mod:UpdatePlates(playerName) end end -function mod:AttachCooldownsToPlate(plate, cooldowns, testMode) +function mod:AttachCooldownsToPlate(plate, cooldowns, inTestMode) local unitType - if not testMode then + if not inTestMode then unitType = plate.UnitType and (find(plate.UnitType, 'ENEMY') and 'ENEMY_PLAYER' or 'FRIENDLY_PLAYER') if not unitType then return end end - local db = testMode and E.db.Extras.nameplates[modName][E.db.Extras.nameplates[modName].selectedType] or E.db.Extras.nameplates[modName][unitType] + local db = E.db.Extras.nameplates[modName][inTestMode and E.db.Extras.nameplates[modName].selectedType or unitType] if not db.enabled then return end @@ -1355,8 +1355,12 @@ function mod:Toggle() twipe(highlightedSpells) twipe(petSpells) - if db['FRIENDLY_PLAYER'].enabled or db['ENEMY_PLAYER'].enabled then - core.plateAnchoring['CDTracker'] = function(unitType) return db[unitType].header end + if not core.reload and (db['FRIENDLY_PLAYER'].enabled or db['ENEMY_PLAYER'].enabled) then + core.plateAnchoring['CDTracker'] = function(unitType) + if unitType == 'FRIENDLY_PLAYER' or unitType == 'ENEMY_PLAYER' then + return db[unitType].header + end + end if not self:IsHooked(NP, "OnShow") then self:SecureHook(NP, "OnShow", function(self) diff --git a/Modules/Nameplates/GuildsTitles.lua b/Modules/Nameplates/GuildsTitles.lua index bbbe36f..14c9752 100644 --- a/Modules/Nameplates/GuildsTitles.lua +++ b/Modules/Nameplates/GuildsTitles.lua @@ -8,17 +8,30 @@ local LSM = E.Libs.LSM local modName = mod:GetName() local NPCOccupations_data = {} local NPCOccupations_cache = {} +local dataTexMap = {} +local dataTexMapDefaults = { + [MINIMAP_TRACKING_AUCTIONEER ] = "Interface\\Minimap\\Tracking\\Auctioneer", + [MINIMAP_TRACKING_BANKER ] = "Interface\\Minimap\\Tracking\\Banker", + [MINIMAP_TRACKING_BATTLEMASTER ] = "Interface\\Minimap\\Tracking\\BattleMaster", + [MINIMAP_TRACKING_TRAINER_CLASS ] = "Interface\\Minimap\\Tracking\\Class", + [MINIMAP_TRACKING_FLIGHTMASTER ] = "Interface\\Minimap\\Tracking\\FlightMaster", + [MINIMAP_TRACKING_INNKEEPER ] = "Interface\\Minimap\\Tracking\\Innkeeper", + [MINIMAP_TRACKING_VENDOR_REAGENT ] = "Interface\\Minimap\\Tracking\\Reagents", + [MINIMAP_TRACKING_REPAIR ] = "Interface\\Minimap\\Tracking\\Repair", + [MINIMAP_TRACKING_STABLEMASTER ] = "Interface\\Minimap\\Tracking\\StableMaster", + [GUILD ] = "Interface\\GossipFrame\\TabardGossipIcon", + [MINIMAP_TRACKING_TRAINER_PROFESSION] = "Interface\\Minimap\\Tracking\\Profession", + [MERCHANT ] = "Interface\\GossipFrame\\VendorGossipIcon", + [BARBERSHOP ] = "Interface\\GossipFrame\\HealerGossipIcon", +} local isAwesome = C_NamePlate local scanner = CreateFrame("GameTooltip", "ExtrasGT_ScanningTooltip", nil, "GameTooltipTemplate") scanner:SetOwner(WorldFrame, "ANCHOR_NONE") -local trackingTypes = {} -local iconIndex = 1 - local max = math.max local _G, pairs, ipairs, tonumber, select = _G, pairs, ipairs, tonumber, select -local twipe, tinsert, tremove, tcontains = table.wipe, table.insert, table.remove, tContains +local twipe, tinsert, tsort = table.wipe, table.insert, table.sort local format, match, find, gsub, sub = string.format, string.match, string.find, string.gsub, string.sub local GetGuildInfo = GetGuildInfo local UnitInRaid, UnitInParty, UnitIsPlayer, UnitGUID = UnitInRaid, UnitInParty, UnitIsPlayer, UnitGUID @@ -26,14 +39,12 @@ local UnitReaction, UnitName, UnitPlayerControlled, UnitCanAttack = UnitReaction local IsResting, IsInInstance = IsResting, IsInInstance local UNKNOWN, UNIT_LEVEL_TEMPLATE = UNKNOWN, UNIT_LEVEL_TEMPLATE local TOOLTIP_UNIT_LEVEL_RACE_CLASS = gsub(table.concat({strsplit(1, string.format(TOOLTIP_UNIT_LEVEL_RACE_CLASS, 1, 1, 1))}), '[%d%p%s]+', '') -local MINIMAP_TRACKING_VENDOR_AMMO, MINIMAP_TRACKING_AUCTIONEER, MINIMAP_TRACKING_BANKER, - MINIMAP_TRACKING_BATTLEMASTER, MINIMAP_TRACKING_TRAINER_CLASS, MINIMAP_TRACKING_VENDOR_FOOD, - MINIMAP_TRACKING_INNKEEPER, MINIMAP_TRACKING_MAILBOX, MINIMAP_TRACKING_VENDOR_POISON, +local MINIMAP_TRACKING_AUCTIONEER, MINIMAP_TRACKING_BANKER, + MINIMAP_TRACKING_BATTLEMASTER, MINIMAP_TRACKING_TRAINER_CLASS, MINIMAP_TRACKING_INNKEEPER, MINIMAP_TRACKING_VENDOR_REAGENT, MINIMAP_TRACKING_TRAINER_PROFESSION, MINIMAP_TRACKING_REPAIR, MINIMAP_TRACKING_STABLEMASTER, MINIMAP_TRACKING_FLIGHTMASTER, BARBERSHOP, GUILD, MERCHANT, ALL = - MINIMAP_TRACKING_VENDOR_AMMO, MINIMAP_TRACKING_AUCTIONEER, MINIMAP_TRACKING_BANKER, - MINIMAP_TRACKING_BATTLEMASTER, MINIMAP_TRACKING_TRAINER_CLASS, MINIMAP_TRACKING_VENDOR_FOOD, - MINIMAP_TRACKING_INNKEEPER, MINIMAP_TRACKING_MAILBOX, MINIMAP_TRACKING_VENDOR_POISON, + MINIMAP_TRACKING_AUCTIONEER, MINIMAP_TRACKING_BANKER, + MINIMAP_TRACKING_BATTLEMASTER, MINIMAP_TRACKING_TRAINER_CLASS, MINIMAP_TRACKING_INNKEEPER, MINIMAP_TRACKING_VENDOR_REAGENT, MINIMAP_TRACKING_TRAINER_PROFESSION, MINIMAP_TRACKING_REPAIR, MINIMAP_TRACKING_STABLEMASTER, MINIMAP_TRACKING_FLIGHTMASTER, BARBERSHOP, GUILD, MERCHANT, ALL @@ -55,53 +66,29 @@ local separatorMap = { CURVE1 = "( %s )" } -local dataTexMap = { - ["Auctioneer"] = "Interface\\Minimap\\Tracking\\Auctioneer", - ["Banker"] = "Interface\\Minimap\\Tracking\\Banker", - ["BattleMaster"] = "Interface\\Minimap\\Tracking\\BattleMaster", - ["Class"] = "Interface\\Minimap\\Tracking\\Class", - ["FlightMaster"] = "Interface\\Minimap\\Tracking\\FlightMaster", - ["Innkeeper"] = "Interface\\Minimap\\Tracking\\Innkeeper", - ["Reagents"] = "Interface\\Minimap\\Tracking\\Reagents", - ["Repair"] = "Interface\\Minimap\\Tracking\\Repair", - ["StableMaster"] = "Interface\\Minimap\\Tracking\\StableMaster", - ["Tabard"] = "Interface\\GossipFrame\\TabardGossipIcon", - ["Profession"] = "Interface\\Minimap\\Tracking\\Profession", - ["Vendor"] = "Interface\\GossipFrame\\VendorGossipIcon", - ["Barber"] = "Interface\\GossipFrame\\HealerGossipIcon", -} - -mod.trackingTexMap = { - "Interface\\Minimap\\Tracking\\Ammunition", -- 1 - "Interface\\Minimap\\Tracking\\Auctioneer", -- 2 - "Interface\\Minimap\\Tracking\\Banker", -- 3 - "Interface\\Minimap\\Tracking\\BattleMaster", -- 4 - "Interface\\Minimap\\Tracking\\Class", -- 5 - "Interface\\Minimap\\Tracking\\Food", -- 6 - "Interface\\Minimap\\Tracking\\Innkeeper", -- 7 - "Interface\\Minimap\\Tracking\\Mailbox", -- 8 - "Interface\\Minimap\\Tracking\\Poisons", -- 9 - "Interface\\Minimap\\Tracking\\Reagents", -- 10 - "Interface\\Minimap\\Tracking\\Profession", -- 11 - "Interface\\Minimap\\Tracking\\Repair", -- 12 - "Interface\\Minimap\\Tracking\\StableMaster", -- 13 - "Interface\\Minimap\\Tracking\\FlightMaster" -- 14 -} - P["Extras"]["nameplates"][modName] = { ["selectedSubSection"] = 'OccupationIcon', ["UnitTitle"] = {}, - ["NPCList"] = {}, - ["GuildList"] = {}, - ["NPCOccupations"] = {}, ["NPCOccupations_cache"] = {}, + ["NPCOccupations_data"] = { + [MINIMAP_TRACKING_AUCTIONEER] = {}, + [MINIMAP_TRACKING_BANKER] = {}, + [MINIMAP_TRACKING_BATTLEMASTER] = {}, + [MINIMAP_TRACKING_TRAINER_CLASS] = {}, + [MINIMAP_TRACKING_FLIGHTMASTER] = {}, + [MINIMAP_TRACKING_INNKEEPER] = {}, + [MINIMAP_TRACKING_VENDOR_REAGENT] = {}, + [MINIMAP_TRACKING_REPAIR] = {}, + [MINIMAP_TRACKING_STABLEMASTER] = {}, + [GUILD] = {}, + [MINIMAP_TRACKING_TRAINER_PROFESSION] = {}, + [MERCHANT] = {}, + [BARBERSHOP] = {}, + }, ["OccupationIcon"] = { ["enabled"] = false, - ["desc"] = L["An icon similar to the minimap search.".. - "\n\nTooltip scanning, might not be precise.".. - "\n\nFor consistency reasons, no keywards are added by defult, ".. - "use /addOccupation command to mark the appropriate ones yourself (only need to do it once per unique occupation text)."], + ["desc"] = L["An icon similar to the minimap search."], ["size"] = 24, ["point"] = "TOP", ["relativeTo"] = "BOTTOM", @@ -109,11 +96,25 @@ P["Extras"]["nameplates"][modName] = { ["yOffset"] = -16, ["level"] = 40, ["anchor"] = "FRAME", - ["playerList"] = {}, - ["playerTextures"] = {}, ["modifier"] = 'Alt', ["backdrop"] = false, ["types"] = {}, + ["selectedOccupation"] = MERCHANT, + ["dataTexMap"] = { + [MINIMAP_TRACKING_AUCTIONEER ] = "Interface\\Minimap\\Tracking\\Auctioneer", + [MINIMAP_TRACKING_BANKER ] = "Interface\\Minimap\\Tracking\\Banker", + [MINIMAP_TRACKING_BATTLEMASTER ] = "Interface\\Minimap\\Tracking\\BattleMaster", + [MINIMAP_TRACKING_TRAINER_CLASS ] = "Interface\\Minimap\\Tracking\\Class", + [MINIMAP_TRACKING_FLIGHTMASTER ] = "Interface\\Minimap\\Tracking\\FlightMaster", + [MINIMAP_TRACKING_INNKEEPER ] = "Interface\\Minimap\\Tracking\\Innkeeper", + [MINIMAP_TRACKING_VENDOR_REAGENT ] = "Interface\\Minimap\\Tracking\\Reagents", + [MINIMAP_TRACKING_REPAIR ] = "Interface\\Minimap\\Tracking\\Repair", + [MINIMAP_TRACKING_STABLEMASTER ] = "Interface\\Minimap\\Tracking\\StableMaster", + [GUILD ] = "Interface\\GossipFrame\\TabardGossipIcon", + [MINIMAP_TRACKING_TRAINER_PROFESSION] = "Interface\\Minimap\\Tracking\\Profession", + [MERCHANT ] = "Interface\\GossipFrame\\VendorGossipIcon", + [BARBERSHOP ] = "Interface\\GossipFrame\\HealerGossipIcon", + }, }, ["Titles"] = { ["enabled"] = false, @@ -249,13 +250,24 @@ function mod:LoadConfig() name = L["Purge Cache"], desc = "", func = function() - if selectedSubSection() == 'OccupationIcon' then - db.NPCOccupations_cache = {} - else - db.UnitTitle = {} - end - self:UpdateAllSettings(db) - print(core.customColorBeta .. L["Cache purged."]) + StaticPopupDialogs["PURGECHACHEDDATA"] = { + text = L["Purge Cache"]..'?', + button1 = YES, + button2 = NO, + OnAccept = function() + if selectedSubSection() == 'OccupationIcon' then + db.NPCOccupations_cache = {} + else + db.UnitTitle = {} + end + self:UpdateAllSettings(db) + print(core.customColorBeta .. L["Cache purged."]) + end, + timeout = 0, + whileDead = true, + hideOnEscape = true, + } + StaticPopup_Show("PURGECHACHEDDATA") end, }, }, @@ -522,115 +534,124 @@ function mod:LoadConfig() desc = "", min = -200, max = 200, step = 1 }, - addOccupation = { + modifier = { order = 8, - type = "input", - name = L["/addOccupation"], - desc = format(L["Usage:\n%%d=%%s\n\n%%d - index from the list below\n%%s - keywords to look for\n\nIndexes of icons:".. - "\n1 - %s".. - "\n2 - %s".. - "\n3 - %s".. - "\n4 - %s".. - "\n5 - %s".. - "\n6 - %s".. - "\n7 - %s".. - "\n8 - %s".. - "\n9 - %s".. - "\n10 - %s".. - "\n11 - %s".. - "\n12 - %s".. - "\n13 - %s".. - "\n14 - %s".. - "\n\n\nAlso available as a '/addOccupation %%d' slash command where %%d is an optional icon index. ".. - "If no index is provided, this command will cycle through all of the available icons. Works on either TARGET or MOUSEOVER, prioritising the latter."], - MINIMAP_TRACKING_VENDOR_AMMO, MINIMAP_TRACKING_AUCTIONEER, MINIMAP_TRACKING_BANKER, MINIMAP_TRACKING_BATTLEMASTER, MINIMAP_TRACKING_TRAINER_CLASS, - MINIMAP_TRACKING_VENDOR_FOOD, MINIMAP_TRACKING_INNKEEPER, MINIMAP_TRACKING_MAILBOX, MINIMAP_TRACKING_VENDOR_POISON, MINIMAP_TRACKING_VENDOR_REAGENT, - MINIMAP_TRACKING_TRAINER_PROFESSION, MINIMAP_TRACKING_REPAIR, MINIMAP_TRACKING_STABLEMASTER, MINIMAP_TRACKING_FLIGHTMASTER), - set = function(_, value) - if value and value ~= "" then - tinsert(db.OccupationIcon.playerList, value) - self:UpdateAllSettings(db) + type = "select", + name = L["Modifier"], + desc = L["Hold this key while using /addOccupation command to clear the list of the current target/mouseover NPC."], + get = function(info) return db.OccupationIcon[info[#info]] end, + set = function(info, value) db.OccupationIcon[info[#info]] = value end, + values = function() + local modsList = {} + for modifier, val in pairs(E.db.Extras.modifiers) do + if modifier ~= 'ANY' then + modsList[modifier] = val + end end + return modsList end, }, - removeOccupation = { + backdrop = { order = 9, + type = "toggle", + name = L["Use Backdrop"], + desc = "", + }, + addOccupation = { + order = 10, + type = "input", + name = L["/addOccupation"], + desc = L["Use /addOccupation slash command while targeting/hovering over a NPC to add it to the list. Use again to cycle."], + get = function() return "/addOccupation" end, + }, + removeOccupation = { + order = 11, type = "select", - name = L["Remove occupation"], + width = "double", + name = L["Remove NPC"], desc = "", values = function() local list = {} - for i = 1, #db.OccupationIcon.playerList do - local entry = db.OccupationIcon.playerList[i] - list[entry] = entry + for occupation, data in pairs(db.NPCOccupations_data) do + for id, name in pairs(data) do + list[id] = format("%s (%s)", name, occupation) end + end return list end, set = function(_, value) - for i, occupation in ipairs(db.OccupationIcon.playerList) do - if occupation == value then - tremove(db.OccupationIcon.playerList, i) + for _, data in pairs(db.NPCOccupations_data) do + for id, name in pairs(data) do + if id == value then + data[id] = nil + db.NPCOccupations_cache[name] = nil + self:UpdateAllSettings(db) + return + end end end - self:UpdateAllSettings(db) end, }, - modifier = { - order = 10, + changeNPCOccupation = { + order = 12, type = "select", - name = L["Modifier"], - desc = L["Hold this while using /addOccupation command to clear the list of the current target/mouseover occupation.\nDon't forget to unbind the modifier+key bind!"], - get = function(info) return db.OccupationIcon[info[#info]] end, - set = function(info, value) db.OccupationIcon[info[#info]] = value end, + width = "double", + name = L["Change NPC's Occupation"], + desc = L["...to the currently selected one."], values = function() - local modsList = {} - for mod, val in pairs(E.db.Extras.modifiers) do - if mod ~= 'ANY' then - modsList[mod] = val + local list = {} + for occupation, data in pairs(db.NPCOccupations_data) do + for id, name in pairs(data) do + list[id] = format("%s (%s)", name, occupation) end end - return modsList + return list end, - }, - addTexture = { - order = 11, - type = "input", - name = L["Add Texture Path"], - desc = L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"], + get = function() return "" end, set = function(_, value) - if value and match(value, '%S+') then - tinsert(mod.trackingTexMap, value) - tinsert(db.OccupationIcon.playerTextures, value) + local occupation = db[selectedSubSection()].selectedOccupation + for oc, data in pairs(db.NPCOccupations_data) do + if oc ~= occupation then + for id, name in pairs(data) do + if id == value then + data[id] = nil + db.NPCOccupations_data[occupation][id] = name + db.NPCOccupations_cache[name] = occupation + self:UpdateAllSettings(db) + return + end + end + end end end, }, - backdrop = { - order = 12, - type = "toggle", - name = L["Use Backdrop"], - desc = "", - }, - removeTexture = { + selectedOccupation = { order = 13, type = "select", width = "double", - name = L["Remove Selected Texture"], + name = L["Select Occupation"], desc = "", - set = function(_, value) - for i in ipairs(db.OccupationIcon.playerTextures) do - if i == value then - tremove(db.OccupationIcon.playerTextures, i) - tremove(mod.trackingTexMap, 14 + i) - end - end - end, values = function() local list = {} - for i, icon in ipairs(db.OccupationIcon.playerTextures) do - list[i] = icon .. ' |T' .. icon .. ':16:16|t' + for occupation in pairs(db.NPCOccupations_data) do + list[occupation] = occupation end return list end, + set = function(_, value) db[selectedSubSection()].selectedOccupation = value end, + }, + dataTexMap = { + order = 14, + type = "input", + width = "double", + name = L["Texture"], + desc = L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"], + get = function() return db.OccupationIcon.dataTexMap[db[selectedSubSection()].selectedOccupation] end, + set = function(_, value) + local occupation = db[selectedSubSection()].selectedOccupation + db.OccupationIcon.dataTexMap[occupation] = value == "" and dataTexMapDefaults[occupation] or value + NP:ConfigureAll() + end, }, }, }, @@ -871,9 +892,6 @@ function mod:LoadConfig() }, }, } - for _, tex in pairs(db.OccupationIcon.playerTextures) do - tinsert(self.trackingTexMap , tex) - end end @@ -890,46 +908,33 @@ local function constructTitle(frame) frame.OccupationIcon.icon:SetAllPoints(frame.OccupationIcon) end -local function findPlateByName(unit) - local name = UnitName(unit) - for plate in pairs(NP.VisiblePlates) do - if plate.UnitName == name then - return plate - end - end -end - -local function manageTitleFrame(frame, title, db, unitType, db_icon) - title.str:SetFont(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline) - title:Height(db.fontSize) - +local function manageTitleFrame(frame, title, db, db_icon) local health = frame.Health - local anchor = health:IsVisible() and health or frame.Name - - title:ClearAllPoints() - title:Point(db.point, anchor, db.relativeTo, db.xOffset, db.yOffset) - title:SetFrameLevel(max(1, frame:GetFrameLevel() + db.level)) - - if not db_icon then return end - - local occupationIcon = frame.OccupationIcon - - if db_icon.anchor ~= "FRAME" then - anchor = title + if db then + title.str:SetFont(LSM:Fetch("font", db.font), db.fontSize, db.fontOutline) + title:Height(db.fontSize) + title:ClearAllPoints() + title:Point(db.point, health:IsVisible() and health or frame.Name, db.relativeTo, db.xOffset, db.yOffset) + title:SetFrameLevel(max(1, frame:GetFrameLevel() + db.level)) end - - occupationIcon:ClearAllPoints() - occupationIcon:Size(db_icon.size) - occupationIcon:Point(db_icon.point, anchor, db_icon.relativeTo, db_icon.xOffset, db_icon.yOffset) - occupationIcon:SetFrameLevel(max(1,frame:GetFrameLevel() + db_icon.level)) - - if db_icon.backdrop then - if not occupationIcon.backdrop then - occupationIcon:CreateBackdrop("Transparent") + if db_icon then + local occupationIcon = frame.OccupationIcon + + occupationIcon:ClearAllPoints() + occupationIcon:Size(db_icon.size) + occupationIcon:Point(db_icon.point, + db_icon.anchor ~= "FRAME" and title or health:IsVisible() and health or frame.Name, + db_icon.relativeTo, db_icon.xOffset, db_icon.yOffset) + occupationIcon:SetFrameLevel(max(1,frame:GetFrameLevel() + db_icon.level)) + + if db_icon.backdrop then + if not occupationIcon.backdrop then + occupationIcon:CreateBackdrop("Transparent") + end + occupationIcon.backdrop:Show() + elseif occupationIcon.backdrop then + occupationIcon.backdrop:Hide() end - occupationIcon.backdrop:Show() - elseif occupationIcon.backdrop then - occupationIcon.backdrop:Hide() end end @@ -941,25 +946,32 @@ function mod:UpdateTitle(frame, db, unit, unitTitle, name) if not unit or not name then return end - local title = frame.Title - local _, unitType = NP:GetUnitInfo(frame) + local title, unitType = frame.Title, frame.UnitType if unitType == 'FRIENDLY_NPC' or unitType == 'ENEMY_NPC' then local iconEnabled = db.OccupationIcon.enabled if not unitTitle or match(unitTitle, UNIT_LEVEL_TEMPLATE) or find(gsub(unitTitle, "[%s%d%p]+", ""), TOOLTIP_UNIT_LEVEL_RACE_CLASS) then if iconEnabled then - manageTitleFrame(frame, title, db.Titles[unitType], unitType, db.OccupationIcon) - self:UpdateOccupation(frame.OccupationIcon, db, unit, unitTitle, name) + if unitType == 'FRIENDLY_NPC' then + manageTitleFrame(frame, title, nil, db.OccupationIcon) + self:UpdateOccupation(frame.OccupationIcon, db, unit, name) + elseif frame.OccupationIcon then + frame.OccupationIcon:Hide() + end end elseif unitTitle and db.Titles.enabled then if not isAwesome and db.UnitTitle[name] ~= unitTitle then db.UnitTitle[name] = unitTitle end if iconEnabled then - manageTitleFrame(frame, title, db.Titles[unitType], unitType, db.OccupationIcon) - self:UpdateOccupation(frame.OccupationIcon, db, unit, unitTitle, name) + manageTitleFrame(frame, title, db.Titles[unitType], db.OccupationIcon) + if unitType == 'FRIENDLY_NPC' then + self:UpdateOccupation(frame.OccupationIcon, db, unit, name) + elseif frame.OccupationIcon then + frame.OccupationIcon:Hide() + end else - manageTitleFrame(frame, title, db.Titles[unitType], unitType) + manageTitleFrame(frame, title, db.Titles[unitType]) end db = db.Titles[unitType] @@ -988,8 +1000,12 @@ function mod:UpdateTitle(frame, db, unit, unitTitle, name) title:Width(title.str:GetStringWidth()) title:Show() elseif iconEnabled then - manageTitleFrame(frame, title, db.Titles[unitType], unitType, db.OccupationIcon) - self:UpdateOccupation(frame.OccupationIcon, db, unit, unitTitle, name) + if unitType == 'FRIENDLY_NPC' then + manageTitleFrame(frame, title, nil, db.OccupationIcon) + self:UpdateOccupation(frame.OccupationIcon, db, unit, name) + elseif frame.OccupationIcon then + frame.OccupationIcon:Hide() + end end elseif unitTitle and db.Guilds.enabled and (unitType == 'FRIENDLY_PLAYER' or unitType == 'ENEMY_PLAYER') then db = db.Guilds[unitType] @@ -1013,7 +1029,7 @@ function mod:UpdateTitle(frame, db, unit, unitTitle, name) end if shown then - manageTitleFrame(frame, title, db, unitType) + manageTitleFrame(frame, title, db) local color @@ -1086,39 +1102,40 @@ function mod:AwesomeUpdateUnitInfo(frame, db, unit) end end -function mod:UpdateOccupation(occupationIcon, db, unit, unitTitle, name) - if db.NPCOccupations[name] then - occupationIcon.icon:SetTexture(db.NPCOccupations[name].icon) - occupationIcon:Show() - return - elseif not isAwesome and NPCOccupations_cache[name] then - occupationIcon.icon:SetTexture(NPCOccupations_cache[name]) - occupationIcon:Show() - return - elseif unitTitle then - for type, icon in pairs(trackingTypes) do - if find(gsub(gsub(unitTitle, '%p+', ''), '%s+', ''), type) then - occupationIcon.icon:SetTexture(icon) - occupationIcon:Show() - db.NPCOccupations[name] = { occupation = type, icon = icon } - return +function mod:UpdateOccupation(occupationIcon, db, unit, name) + if not isAwesome then + local cachedOccupation = NPCOccupations_cache[name] + if cachedOccupation then + occupationIcon.icon:SetTexture(dataTexMap[cachedOccupation]) + occupationIcon:Show() + return + else + local guid = unit and UnitGUID(unit) + if guid then + local npcId = tonumber(sub(guid, -10, -7), 16) + for occupation, entries in pairs(NPCOccupations_data) do + if entries[npcId] then + occupationIcon.icon:SetTexture(dataTexMap[occupation]) + occupationIcon:Show() + if not db.NPCOccupations_cache[name] then + db.NPCOccupations_cache[name] = occupation + NPCOccupations_cache[name] = occupation + end + return + end + end end end - end - - local guid = unit and UnitGUID(unit) - if guid and not UnitCanAttack('player', unit) then - local npcId = tonumber(sub(guid, -10, -7), 16) - for occupation, entries in pairs(NPCOccupations_data) do - if tcontains(entries, npcId) then - local tex = dataTexMap[occupation] - occupationIcon.icon:SetTexture(tex) - occupationIcon:Show() - if not isAwesome and not db.NPCOccupations_cache[name] then - db.NPCOccupations_cache[name] = { occupation = occupation, tex = tex } - NPCOccupations_cache[name] = tex + else + local guid = unit and UnitGUID(unit) + if guid then + local npcId = tonumber(sub(guid, -10, -7), 16) + for occupation, entries in pairs(NPCOccupations_data) do + if entries[npcId] then + occupationIcon.icon:SetTexture(dataTexMap[occupation]) + occupationIcon:Show() + return end - return end end end @@ -1148,7 +1165,6 @@ function mod:UpdateUnitInfo(frame, db, unit) E_Delay(nil, 0.1, function() if name ~= UnitName(unit) then return end - guildName = GetGuildInfo(unit) if guildName then mod:UpdateTitle(frame, db, unit, guildName, name) @@ -1169,7 +1185,18 @@ function mod:UpdateUnitInfo(frame, db, unit) local name = _G["ExtrasGT_ScanningTooltipTextLeft1"]:GetText() if not name then return end local description = _G["ExtrasGT_ScanningTooltipTextLeft2"]:GetText() - if not description then return end + if not description then + if db.OccupationIcon.enabled then + local unitType = frame.UnitType + if unitType == 'FRIENDLY_NPC' then + manageTitleFrame(frame, frame.Title, nil, db.OccupationIcon) + self:UpdateOccupation(frame.OccupationIcon, db, unit, name) + elseif frame.OccupationIcon then + frame.OccupationIcon:Hide() + end + end + return + end name = gsub(gsub((name), "|c........", ""), "|r", "") if name ~= UnitName(unit) then return end @@ -1178,38 +1205,37 @@ function mod:UpdateUnitInfo(frame, db, unit) end end -function mod:UpdateTrackingTypes(db) - twipe(trackingTypes) +function mod:UpdateAllSettings(db) twipe(NPCOccupations_data) twipe(NPCOccupations_cache) - if #db.OccupationIcon.playerList > 0 then - for i = 1, #db.OccupationIcon.playerList do - local entry = db.OccupationIcon.playerList[i] - local iconIndex, occupation = match(entry, '(%d+)%s*=%s*(.+)') - if iconIndex and occupation then - trackingTypes[gsub(gsub(occupation, '%p+', ''), '%s+', '')] = self.trackingTexMap[tonumber(iconIndex)] + dataTexMap = db.OccupationIcon.dataTexMap + local all = db.OccupationIcon.types["All"] + for occupation, data in pairs(core.NPCOccupations_data or {}) do + if all or db.OccupationIcon.types[occupation] then + NPCOccupations_data[occupation] = {} + local occupation_data = NPCOccupations_data[occupation] + for id in pairs(data) do + occupation_data[id] = true end end end - for name, info in pairs(db.NPCOccupations) do - if not trackingTypes[info.occupation] or trackingTypes[info.occupation] ~= info.icon then - db.NPCOccupations[name] = nil - end - end - local all = db.OccupationIcon.types["All"] - for occupation, data in pairs(core.NPCOccupations_data or {}) do + for occupation, data in pairs(db.NPCOccupations_data) do if all or db.OccupationIcon.types[occupation] then - NPCOccupations_data[occupation] = data + NPCOccupations_data[occupation] = NPCOccupations_data[occupation] or {} + local occupation_data = NPCOccupations_data[occupation] + for id in pairs(data) do + occupation_data[id] = true + end end end - for name, info in pairs(db.NPCOccupations_cache) do - if all or db.OccupationIcon.types[info.occupation] then - NPCOccupations_cache[name] = info.tex + for name, occupation in pairs(db.NPCOccupations_cache) do + if all or db.OccupationIcon.types[occupation] then + NPCOccupations_cache[name] = occupation end end if db.OccupationIcon.enabled then if db.OccupationIcon.anchor == "FRAME" then - core.plateAnchoring['OccupationIcon'] = function(unitType, frame) + core.plateAnchoring['OccupationIcon'] = function(unitType) if unitType == 'FRIENDLY_NPC' or unitType == 'ENEMY_NPC' then return db.OccupationIcon end @@ -1220,63 +1246,96 @@ function mod:UpdateTrackingTypes(db) else core.plateAnchoring['OccupationIcon'] = nil end -end - -function mod:UpdateAllSettings(db) - self:UpdateTrackingTypes(db) - for frame in pairs(NP.VisiblePlates) do - if frame.Title then frame.Title:Hide() end + for plate in pairs(NP.CreatedPlates) do + local frame = plate and plate.UnitFrame + if frame then + if frame.Title then frame.Title:Hide() end + if frame.OccupationIcon then frame.OccupationIcon:Hide() end + end + end + if not core.reload then + NP:ConfigureAll() end - NP:ConfigureAll() end -function mod:addOccupation(msg) +function mod:addOccupation() local db = E.db.Extras.nameplates[modName] for _, unit in ipairs({'mouseover', 'target'}) do - if not UnitIsPlayer(unit) then - scanner:ClearLines() - scanner:SetUnit(unit) - local name = _G["ExtrasGT_ScanningTooltipTextLeft1"]:GetText() - local title = _G["ExtrasGT_ScanningTooltipTextLeft2"]:GetText() - if name and title then - if not match(title, UNIT_LEVEL_TEMPLATE) then - if _G['Is'..db.OccupationIcon.modifier..'KeyDown']() then - for i, occupation in ipairs(db.OccupationIcon.playerList) do - if find(gsub(gsub(occupation, '%p+', ''), '%s+', ''), gsub(gsub(title, '%p+', ''), '%s+', '')) then - tremove(db.OccupationIcon.playerList, i) - self:UpdateAllSettings(db) - return - end + if not UnitIsPlayer(unit) and not UnitCanAttack('player', unit) then + local guid = UnitGUID(unit) + local npcId = guid and tonumber(sub(guid, -10, -7), 16) + if npcId then + local name = UnitName(unit) + if _G['Is'..db.OccupationIcon.modifier..'KeyDown']() then + for occupation, entries in pairs(NPCOccupations_data) do + if entries[npcId] then + entries[npcId] = nil + db.NPCOccupations_data[occupation][npcId] = nil + db.NPCOccupations_cache[name] = nil + NPCOccupations_cache[name] = nil + NP:ConfigureAll() + if E.RefreshGUI then E:RefreshGUI() end + return end end - local icon = find(msg, '%d+') and msg or iconIndex - for i, occupation in ipairs(db.OccupationIcon.playerList) do - if find(gsub(gsub(occupation, '%p+', ''), '%s+', ''), gsub(gsub(title, '%p+', ''), '%s+', '')) then - db.OccupationIcon.playerList[i] = icon.."="..title - iconIndex = (iconIndex % #self.trackingTexMap) + 1 - self:UpdateAllSettings(db) - return + end + for _, entries in pairs(core.NPCOccupations_data or {}) do + if entries[npcId] then + return + end + end + local foundOccupation + local order = {} + for occupation, entries in pairs(db.NPCOccupations_data) do + if not foundOccupation and entries[npcId] then + entries[npcId] = nil + NPCOccupations_data[occupation][npcId] = nil + NPCOccupations_cache[name] = nil + db.NPCOccupations_cache[name] = nil + foundOccupation = occupation + end + tinsert(order, occupation) + end + if foundOccupation then + tsort(order) + for i, occupation in ipairs(order) do + if occupation == foundOccupation then + local newOccupation = order[i % #order+1] + NPCOccupations_data[newOccupation][npcId] = name + db.NPCOccupations_data[newOccupation][npcId] = name + NPCOccupations_cache[name] = newOccupation + db.NPCOccupations_cache[name] = newOccupation + break end end - tinsert(db.OccupationIcon.playerList, icon.."="..title) - iconIndex = (iconIndex % #self.trackingTexMap) + 1 - self:UpdateAllSettings(db) - return + else + NPCOccupations_data[MERCHANT][npcId] = name + db.NPCOccupations_data[MERCHANT][npcId] = name + NPCOccupations_cache[name] = MERCHANT + db.NPCOccupations_cache[name] = MERCHANT end + NP:ConfigureAll() + if E.RefreshGUI then E:RefreshGUI() end + return end end end end function mod:OnEvent(db, unit) - local frame = findPlateByName(unit) - if not frame then return end - self:UpdateUnitInfo(frame, db, unit) + local name = UnitName(unit) + if name then + for frame in pairs(NP.VisiblePlates) do + if frame.UnitName == name then + self:UpdateUnitInfo(frame, db, unit) + end + end + end end function mod:Toggle(db) - if not db.Guilds.enabled and not db.Titles.enabled and not db.OccupationIcon.enabled then + if core.reload or (not db.Guilds.enabled and not db.Titles.enabled and not db.OccupationIcon.enabled) then if not db.Guilds.enabled and not db.Titles.enabled then core.plateAnchoring['Title'] = nil end @@ -1293,7 +1352,7 @@ function mod:Toggle(db) hash_SlashCmdList["/ADDOCCUPATION"] = nil else if db.Guilds.enabled or db.Titles.enabled then - core.plateAnchoring['Title'] = function(unitType, frame) + core.plateAnchoring['Title'] = function(unitType) if unitType == 'FRIENDLY_NPC' or unitType == 'ENEMY_NPC' then return db.Titles[unitType] elseif unitType == 'FRIENDLY_PLAYER' or unitType == 'ENEMY_PLAYER' then @@ -1306,8 +1365,8 @@ function mod:Toggle(db) self:RegisterEvent("RAID_ROSTER_UPDATE", function() self:UpdateAllSettings(db) end) if isAwesome then if not self:IsHooked(NP, "OnCreated") then - self:SecureHook(NP, "OnCreated", function(self, frame) - constructTitle(frame.UnitFrame) + self:SecureHook(NP, "OnCreated", function(self, plate) + constructTitle(plate.UnitFrame) end) end if not self:IsHooked(NP, "OnShow") then @@ -1337,15 +1396,25 @@ function mod:Toggle(db) end end) end - if not self:IsHooked(NP, "OnShow") then - self:SecureHook(NP, "OnShow", function(self) - local frame = self.UnitFrame + if not self:IsHooked(NP, "OnCreated") then + self:SecureHook(NP, "OnCreated", function(self, plate) + local frame = plate.UnitFrame constructTitle(frame) frame.Title:Hide() frame.OccupationIcon:Hide() mod:UpdateTitle(frame, db, nil, nil, frame.UnitName) end) end + if not self:IsHooked(NP, "OnShow") then + self:SecureHook(NP, "OnShow", function(self) + local frame = self.UnitFrame + if frame and frame.Title then + frame.Title:Hide() + frame.OccupationIcon:Hide() + mod:UpdateTitle(frame, db, nil, nil, frame.UnitName) + end + end) + end end if db.OccupationIcon.enabled then SLASH_ADDOCCUPATION1 = "/addOccupation" diff --git a/Modules/Nameplates/GuildsTitles_data.lua b/Modules/Nameplates/GuildsTitles_data.lua index 3489aea..d5820c7 100644 --- a/Modules/Nameplates/GuildsTitles_data.lua +++ b/Modules/Nameplates/GuildsTitles_data.lua @@ -1,3482 +1,3482 @@ ElvUI[1]:GetModule("Extras").NPCOccupations_data = { - ["Auctioneer"] = { - 35594, -- Brassbolt Mechawrench - 35607, -- Reginald Arcfire - 9857, -- Auctioneer Grizzlin - 8720, -- Auctioneer Redmuse - 16627, -- Ithillan - 15682, -- Auctioneer Cain - 15684, -- Auctioneer Tricket - 8661, -- Auctioneer Beardo - 9858, -- Auctioneer Kresky - 15681, -- Auctioneer O'reely - 15675, -- Auctioneer Stockton - 8673, -- Auctioneer Thathung - 8669, -- Auctioneer Tolon - 15676, -- Auctioneer Yarly - 16629, -- Tandron - 8672, -- Auctioneer Leeka - 16707, -- Eoch - 15679, -- Auctioneer Cazarez - 8721, -- Auctioneer Epitwee - 9859, -- Auctioneer Lympkin - 15683, -- Auctioneer Naxxremis - 16628, -- Caidori - 17629, -- Feynna - 18349, -- Iressa - 8671, -- Auctioneer Buckler - 15677, -- Auctioneer Graves - 8722, -- Auctioneer Gullem - 15686, -- Auctioneer Rhyker - 15678, -- Auctioneer Silva'las - 8674, -- Auctioneer Stampi - 8724, -- Auctioneer Wabang - 18761, -- Darise - 17627, -- Jenath - 8719, -- Auctioneer Fitch - 15659, -- Auctioneer Jaxon - 8670, -- Auctioneer Chilton - 18348, -- Fanin - 8723, -- Auctioneer Golothas - 17628, -- Vynna - 9856, -- Auctioneer Grimful + [MINIMAP_TRACKING_AUCTIONEER] = { + [35594] = true, -- Brassbolt Mechawrench + [35607] = true, -- Reginald Arcfire + [9857] = true, -- Auctioneer Grizzlin + [8720] = true, -- Auctioneer Redmuse + [16627] = true, -- Ithillan + [15682] = true, -- Auctioneer Cain + [15684] = true, -- Auctioneer Tricket + [8661] = true, -- Auctioneer Beardo + [9858] = true, -- Auctioneer Kresky + [15681] = true, -- Auctioneer O'reely + [15675] = true, -- Auctioneer Stockton + [8673] = true, -- Auctioneer Thathung + [8669] = true, -- Auctioneer Tolon + [15676] = true, -- Auctioneer Yarly + [16629] = true, -- Tandron + [8672] = true, -- Auctioneer Leeka + [16707] = true, -- Eoch + [15679] = true, -- Auctioneer Cazarez + [8721] = true, -- Auctioneer Epitwee + [9859] = true, -- Auctioneer Lympkin + [15683] = true, -- Auctioneer Naxxremis + [16628] = true, -- Caidori + [17629] = true, -- Feynna + [18349] = true, -- Iressa + [8671] = true, -- Auctioneer Buckler + [15677] = true, -- Auctioneer Graves + [8722] = true, -- Auctioneer Gullem + [15686] = true, -- Auctioneer Rhyker + [15678] = true, -- Auctioneer Silva'las + [8674] = true, -- Auctioneer Stampi + [8724] = true, -- Auctioneer Wabang + [18761] = true, -- Darise + [17627] = true, -- Jenath + [8719] = true, -- Auctioneer Fitch + [15659] = true, -- Auctioneer Jaxon + [8670] = true, -- Auctioneer Chilton + [18348] = true, -- Fanin + [8723] = true, -- Auctioneer Golothas + [17628] = true, -- Vynna + [9856] = true, -- Auctioneer Grimful }, - ["Banker"] = { - 2460, -- Barnum Stonemantle - 29530, -- Binzik Goldbook - 35642, -- Jeeves - 30607, -- Teller Plushner - 8123, -- Rickle Goldgrubber - 8357, -- Atepa - 13917, -- Izzy Coppergrab - 19034, -- Mendorn - 28677, -- Teller Hanners - 19246, -- Berudan Keysworn - 30606, -- Paymaster Chang - 2455, -- Olivia Burnside - 28679, -- Teller Duta - 2996, -- Torn - 8356, -- Chesmu - 4209, -- Garryeth - 2458, -- Randolph Montague - 5099, -- Soleil Stonemantle - 28680, -- Teller Banning - 16617, -- Daenice - 36284, -- Flint Ironstag - 4155, -- Idriana - 18350, -- Jaela - 2457, -- John Burnside - 3309, -- Karus - 31420, -- Karus - 21733, -- Karzo - 19338, -- L'lura Goldspun - 28343, -- Meeda - 2456, -- Newton Burnside - 30608, -- Paymaster Amadi - 29283, -- Paymaster Habert - 16616, -- Periel - 31422, -- Soran - 28678, -- Teller Halder - 28675, -- Teller Rames - 36352, -- Trunk Slamchest - 2625, -- Viznik Goldgrubber - 8119, -- Zikkel - 38920, -- [PH] Grimtotem Banker 2 - 2461, -- Bailey Stonemantle - 17631, -- Ceera - 17632, -- Elana - 3496, -- Fuzruckle - 7799, -- Gimblethorn - 19318, -- Gromden - 17633, -- Hatheon - 16710, -- Kellag - 3318, -- Koma - 31421, -- Koma - 4208, -- Lairn - 2459, -- Mortimer Montague - 21732, -- Nandirx - 16615, -- Novia - 4550, -- Ophelia Montague - 17773, -- Ossco - 29282, -- Paymaster Alstein - 8124, -- Qizzik - 36351, -- Slab Bulkhead - 3320, -- Soran - 30604, -- Teller Almeida - 28676, -- Teller Althiellis - 30605, -- Teller Gee - 4549, -- William Montague - 5060, -- World Banker - 21734, -- Zixxy - 38919, -- [PH] Grimtotem Banker - 38921, -- [PH] Grimtotem Banker 3 + [MINIMAP_TRACKING_BANKER] = { + [2460] = true, -- Barnum Stonemantle + [29530] = true, -- Binzik Goldbook + [35642] = true, -- Jeeves + [30607] = true, -- Teller Plushner + [8123] = true, -- Rickle Goldgrubber + [8357] = true, -- Atepa + [13917] = true, -- Izzy Coppergrab + [19034] = true, -- Mendorn + [28677] = true, -- Teller Hanners + [19246] = true, -- Berudan Keysworn + [30606] = true, -- Paymaster Chang + [2455] = true, -- Olivia Burnside + [28679] = true, -- Teller Duta + [2996] = true, -- Torn + [8356] = true, -- Chesmu + [4209] = true, -- Garryeth + [2458] = true, -- Randolph Montague + [5099] = true, -- Soleil Stonemantle + [28680] = true, -- Teller Banning + [16617] = true, -- Daenice + [36284] = true, -- Flint Ironstag + [4155] = true, -- Idriana + [18350] = true, -- Jaela + [2457] = true, -- John Burnside + [3309] = true, -- Karus + [31420] = true, -- Karus + [21733] = true, -- Karzo + [19338] = true, -- L'lura Goldspun + [28343] = true, -- Meeda + [2456] = true, -- Newton Burnside + [30608] = true, -- Paymaster Amadi + [29283] = true, -- Paymaster Habert + [16616] = true, -- Periel + [31422] = true, -- Soran + [28678] = true, -- Teller Halder + [28675] = true, -- Teller Rames + [36352] = true, -- Trunk Slamchest + [2625] = true, -- Viznik Goldgrubber + [8119] = true, -- Zikkel + [38920] = true, -- [PH] Grimtotem Banker [2] = true + [2461] = true, -- Bailey Stonemantle + [17631] = true, -- Ceera + [17632] = true, -- Elana + [3496] = true, -- Fuzruckle + [7799] = true, -- Gimblethorn + [19318] = true, -- Gromden + [17633] = true, -- Hatheon + [16710] = true, -- Kellag + [3318] = true, -- Koma + [31421] = true, -- Koma + [4208] = true, -- Lairn + [2459] = true, -- Mortimer Montague + [21732] = true, -- Nandirx + [16615] = true, -- Novia + [4550] = true, -- Ophelia Montague + [17773] = true, -- Ossco + [29282] = true, -- Paymaster Alstein + [8124] = true, -- Qizzik + [36351] = true, -- Slab Bulkhead + [3320] = true, -- Soran + [30604] = true, -- Teller Almeida + [28676] = true, -- Teller Althiellis + [30605] = true, -- Teller Gee + [4549] = true, -- William Montague + [5060] = true, -- World Banker + [21734] = true, -- Zixxy + [38919] = true, -- [PH] Grimtotem Banker + [38921] = true, -- [PH] Grimtotem Banker [3] = true }, - ["Barber"] = { - 29142, -- Jelinek Sharpshear - 29141, -- Pella Brassbrush - 29143, -- Bebri Coifcurl - 29139, -- Naznik Sureshave - 29145, -- Pulik Swiftsnip - 28708, -- Kizi Copperclip + [BARBERSHOP] = { + [29142] = true, -- Jelinek Sharpshear + [29141] = true, -- Pella Brassbrush + [29143] = true, -- Bebri Coifcurl + [29139] = true, -- Naznik Sureshave + [29145] = true, -- Pulik Swiftsnip + [28708] = true, -- Kizi Copperclip }, - ["BattleMaster"] = { - 7410, -- Thelman Slatefist - 19858, -- "Lefty" Puddemup - 14982, -- Lylandris - 20374, -- Kandaar - 34955, -- Karg Skullgore - 34983, -- Deathstalker Fane - 29675, -- Eye of the Storm Portal - 14991, -- League of Arathor Emissary - 34985, -- Misery - 29676, -- Strand of the Ancients Portal - 34952, -- Isle of Conquest Portal - 34973, -- Irissa Bloodstar - 19908, -- Su'ura Swiftarrow - 22015, -- Eye of the Storm Envoy - 34976, -- Ruk Warstomper - 35008, -- Sawemba - 19906, -- Usha Eyegouge - 20276, -- Wolf-Sister Maka - 3890, -- Brakgul Deathbringer - 12198, -- Martin Lindsey - 15103, -- Stormpike Emissary - 29671, -- Strand of the Ancients Portal - 29674, -- Alterac Valley Portal - 12197, -- Glordrum Steelbeard - 907, -- Keras Wolfheart - 34988, -- Landuen Moonclaw - 34989, -- Rissa Shadeleaf - 30610, -- War-Hunter Molog - 20273, -- Adam Eternum - 40413, -- Alenjon Sunblade - 35002, -- Asara Dawnblaze - 34991, -- Borim Goldhammer - 29670, -- Eye of the Storm Portal - 20118, -- Jihi - 35007, -- Lixa Felflinger - 19925, -- Miglik Blotstrom - 32332, -- Ramik Slamwrench - 29667, -- Warsong Gulch Portal - 2302, -- Aethalas - 34998, -- Alison Devay - 29668, -- Arathi Basin Portal - 34997, -- Devin Fardale - 10360, -- Kergul Bloodaxe - 15008, -- Lady Hoteshem - 35000, -- Mijiri - 15007, -- Sir Malory Wheeler - 30567, -- Strand of the Ancients Envoy - 29568, -- "Techs" Rickard Rustbolt - 29669, -- Alterac Valley Portal - 29673, -- Arathi Basin Portal - 5118, -- Brogun Stoneshield - 857, -- Donal Osgood - 18895, -- Ear-Biter - 22013, -- Eye of the Storm Emissary - 15106, -- Frostwolf Emissary - 19910, -- Gargok - 347, -- Grizzle Halfmane - 19907, -- Grumbol Grimhammer - 34987, -- Hunara - 25991, -- Kixi the Shiv - 2804, -- Kurden Bloodclaw - 20119, -- Mahul - 19859, -- Max Luna - 34978, -- Mosha Starhorn - 30231, -- Radulf Leder - 35001, -- Saeld Brightflare - 29533, -- Schembari "Uncle Sal" Shearbolt - 30566, -- Strand of the Ancients Emissary - 7427, -- Taim Ragetotem - 19905, -- The Black Bride - 20120, -- Tolo - 15105, -- Warsong Emissary - 29672, -- Warsong Gulch Portal - 21235, -- "Backstab" Bindo Gearbomb - 32333, -- "Dapper" Danik Blackshaft - 20388, -- Althallen Brightblade - 20385, -- Andrissa Heartspear - 19911, -- Beka Zipwhistle - 19923, -- Bipp Glizzitor - 14990, -- Defilers Emissary - 15006, -- Deze Snowbane - 14981, -- Elfarran - 20383, -- Enlae - 20497, -- Fima Five-Fingers - 20499, -- Fizim Blastwrench - 16695, -- Gurak - 20271, -- Haelga Slatefist - 20362, -- Iravar - 34999, -- Jonru - 20381, -- Jovil - 16694, -- Karen Wentworth - 14942, -- Kartra Bloodsnarl - 20274, -- Keldor the Lost - 16696, -- Krukk - 20272, -- Lylandor - 20386, -- Lyrlia Blackshield - 19915, -- Max Xim - 32330, -- Minzi the Minx - 20269, -- Montok Redhands - 19909, -- Rex Pixem - 15102, -- Silverwing Emissary - 19855, -- Sir Maximus Adams - 20384, -- Yula the Fair - 19912, -- Zeggon Botsnap + [MINIMAP_TRACKING_BATTLEMASTER] = { + [7410] = true, -- Thelman Slatefist + [19858] = true, -- "Lefty" Puddemup + [14982] = true, -- Lylandris + [20374] = true, -- Kandaar + [34955] = true, -- Karg Skullgore + [34983] = true, -- Deathstalker Fane + [29675] = true, -- Eye of the Storm Portal + [14991] = true, -- League of Arathor Emissary + [34985] = true, -- Misery + [29676] = true, -- Strand of the Ancients Portal + [34952] = true, -- Isle of Conquest Portal + [34973] = true, -- Irissa Bloodstar + [19908] = true, -- Su'ura Swiftarrow + [22015] = true, -- Eye of the Storm Envoy + [34976] = true, -- Ruk Warstomper + [35008] = true, -- Sawemba + [19906] = true, -- Usha Eyegouge + [20276] = true, -- Wolf-Sister Maka + [3890] = true, -- Brakgul Deathbringer + [12198] = true, -- Martin Lindsey + [15103] = true, -- Stormpike Emissary + [29671] = true, -- Strand of the Ancients Portal + [29674] = true, -- Alterac Valley Portal + [12197] = true, -- Glordrum Steelbeard + [907] = true, -- Keras Wolfheart + [34988] = true, -- Landuen Moonclaw + [34989] = true, -- Rissa Shadeleaf + [30610] = true, -- War-Hunter Molog + [20273] = true, -- Adam Eternum + [40413] = true, -- Alenjon Sunblade + [35002] = true, -- Asara Dawnblaze + [34991] = true, -- Borim Goldhammer + [29670] = true, -- Eye of the Storm Portal + [20118] = true, -- Jihi + [35007] = true, -- Lixa Felflinger + [19925] = true, -- Miglik Blotstrom + [32332] = true, -- Ramik Slamwrench + [29667] = true, -- Warsong Gulch Portal + [2302] = true, -- Aethalas + [34998] = true, -- Alison Devay + [29668] = true, -- Arathi Basin Portal + [34997] = true, -- Devin Fardale + [10360] = true, -- Kergul Bloodaxe + [15008] = true, -- Lady Hoteshem + [35000] = true, -- Mijiri + [15007] = true, -- Sir Malory Wheeler + [30567] = true, -- Strand of the Ancients Envoy + [29568] = true, -- "Techs" Rickard Rustbolt + [29669] = true, -- Alterac Valley Portal + [29673] = true, -- Arathi Basin Portal + [5118] = true, -- Brogun Stoneshield + [857] = true, -- Donal Osgood + [18895] = true, -- Ear-Biter + [22013] = true, -- Eye of the Storm Emissary + [15106] = true, -- Frostwolf Emissary + [19910] = true, -- Gargok + [347] = true, -- Grizzle Halfmane + [19907] = true, -- Grumbol Grimhammer + [34987] = true, -- Hunara + [25991] = true, -- Kixi the Shiv + [2804] = true, -- Kurden Bloodclaw + [20119] = true, -- Mahul + [19859] = true, -- Max Luna + [34978] = true, -- Mosha Starhorn + [30231] = true, -- Radulf Leder + [35001] = true, -- Saeld Brightflare + [29533] = true, -- Schembari "Uncle Sal" Shearbolt + [30566] = true, -- Strand of the Ancients Emissary + [7427] = true, -- Taim Ragetotem + [19905] = true, -- The Black Bride + [20120] = true, -- Tolo + [15105] = true, -- Warsong Emissary + [29672] = true, -- Warsong Gulch Portal + [21235] = true, -- "Backstab" Bindo Gearbomb + [32333] = true, -- "Dapper" Danik Blackshaft + [20388] = true, -- Althallen Brightblade + [20385] = true, -- Andrissa Heartspear + [19911] = true, -- Beka Zipwhistle + [19923] = true, -- Bipp Glizzitor + [14990] = true, -- Defilers Emissary + [15006] = true, -- Deze Snowbane + [14981] = true, -- Elfarran + [20383] = true, -- Enlae + [20497] = true, -- Fima Five-Fingers + [20499] = true, -- Fizim Blastwrench + [16695] = true, -- Gurak + [20271] = true, -- Haelga Slatefist + [20362] = true, -- Iravar + [34999] = true, -- Jonru + [20381] = true, -- Jovil + [16694] = true, -- Karen Wentworth + [14942] = true, -- Kartra Bloodsnarl + [20274] = true, -- Keldor the Lost + [16696] = true, -- Krukk + [20272] = true, -- Lylandor + [20386] = true, -- Lyrlia Blackshield + [19915] = true, -- Max Xim + [32330] = true, -- Minzi the Minx + [20269] = true, -- Montok Redhands + [19909] = true, -- Rex Pixem + [15102] = true, -- Silverwing Emissary + [19855] = true, -- Sir Maximus Adams + [20384] = true, -- Yula the Fair + [19912] = true, -- Zeggon Botsnap }, - ["Class"] = { - 12042, -- Loganaar - 5885, -- Deino - 5497, -- Jennea Cannon - 29195, -- Lady Alistra - 29194, -- Amal'thazad - 5504, -- Sheldras Moontree - 4218, -- Denatharion - 4217, -- Mathrengyl Bearwalker - 3326, -- Zevrost - 4146, -- Jocaste - 4563, -- Kaal Soulreaper - 3032, -- Beram Skychaser - 4205, -- Dorion - 5515, -- Einris Brightspear - 3344, -- Kardris Dreamseeker - 16681, -- Champion Bachi - 4568, -- Anastasia Hartwell - 5149, -- Brandur Ironhammer - 376, -- High Priestess Laurena - 5491, -- Arthur the Faithful - 5489, -- Brother Joshua - 4219, -- Fylerian Nightwing - 928, -- Lord Grayson Shadowbreaker - 11401, -- Priestess Alathea - 3401, -- Shenthul - 17219, -- Sulaa - 6018, -- Ur'kyo - 4606, -- Aelthalyste - 17120, -- Behomat - 16653, -- Inethven - 3352, -- Ormak Grimshot - 5144, -- Bink - 5498, -- Elsharin - 17509, -- Jol - 3030, -- Siln Skychaser - 3354, -- Sorek - 5479, -- Wu Shen - 4595, -- Baltus Fowler - 5484, -- Brother Benjamin - 23127, -- Farseer Javad - 5492, -- Katherine the Pure - 5116, -- Olmin Burningbeard - 3407, -- Sian'dur - 4163, -- Syurna - 5147, -- Valgar Highforge - 7312, -- Dink - 20407, -- Farseer Umbrua - 3353, -- Grezz Ragefist - 17520, -- Gurrag - 23128, -- Master Pyreanor - 3041, -- Torm Ragetotem - 16651, -- Zaedana - 5173, -- Alexander Calder - 4582, -- Carolyn Ward - 3039, -- Holt Thunderhorn - 3038, -- Kary Thunderhorn - 3036, -- Kym Wildmane - 13283, -- Lord Tony Romano - 5166, -- Ormyr Flinteye - 16647, -- Talionia - 3033, -- Turak Runetotem - 16771, -- Ahonan - 5148, -- Beldruk Doombrow - 5883, -- Enyo - 17204, -- Farseer Nobundo - 5165, -- Hulfdan Blackbeard - 5145, -- Juli Stormkettle - 16679, -- Osselan - 5171, -- Thistleheart - 5516, -- Ulfir Ironbeard - 3048, -- Ursyn Ghull - 7311, -- Uthel'nay - 5142, -- Braenna Flintcrag - 5172, -- Briarthorn - 7315, -- Darnath Bladesinger - 16749, -- Edirah - 5167, -- Fenthwick - 11406, -- High Priest Rohan - 4566, -- Kaelystia Hatebringer - 4092, -- Lariia - 16659, -- Lotheolan - 4583, -- Miles Dexter - 3325, -- Mirket - 918, -- Osborne the Night Man - 5882, -- Pephredo - 5496, -- Sandahl - 3040, -- Urek Thunderhorn - 5495, -- Ursula Deline - 3406, -- Xor'juul - 16648, -- Zanien - 3047, -- Archmage Shymm - 20406, -- Champion Cyssa Dawnrose - 5115, -- Daera Brightspear - 461, -- Demisette Cloyce - 4608, -- Father Lazarus - 3327, -- Gest - 3324, -- Grol'dar - 16680, -- Ithelis - 4091, -- Jandria - 1901, -- Kelstrum Stonebreaker - 5113, -- Kelv Sternhammer - 17505, -- Killac - 29196, -- Lord Thorval - 4564, -- Luther Pickman - 331, -- Maginor Dumas - 3328, -- Ormok - 4567, -- Pierce Shackleton - 16652, -- Quithas - 5117, -- Regnus Thundergranite - 4565, -- Richard Kerwin - 13417, -- Sagorne Creststrider - 4089, -- Sildanair - 16672, -- Tana - 5505, -- Theridran - 3049, -- Thurston Xane - 3031, -- Tigor Skychaser - 5143, -- Toldren Deepiron - 6014, -- X'yera - 5994, -- Zayus - 914, -- Ander Germaine - 4594, -- Angela Curthas - 4087, -- Arias'ta Bladesinger - 5114, -- Bilban Tosslespanner - 4593, -- Christoph Walker - 4607, -- Father Lankester - 4584, -- Gregory Charles - 5480, -- Ilsa Corbin - 3043, -- Ker Ragetotem - 3045, -- Malakai Cross - 3044, -- Miles Welsh - 16673, -- Oninath - 3042, -- Sark Ragetotem - 3034, -- Sheal Runetotem - 3403, -- Sian'tsu - 3408, -- Zel'mak + [MINIMAP_TRACKING_TRAINER_CLASS] = { + [12042] = true, -- Loganaar + [5885] = true, -- Deino + [5497] = true, -- Jennea Cannon + [29195] = true, -- Lady Alistra + [29194] = true, -- Amal'thazad + [5504] = true, -- Sheldras Moontree + [4218] = true, -- Denatharion + [4217] = true, -- Mathrengyl Bearwalker + [3326] = true, -- Zevrost + [4146] = true, -- Jocaste + [4563] = true, -- Kaal Soulreaper + [3032] = true, -- Beram Skychaser + [4205] = true, -- Dorion + [5515] = true, -- Einris Brightspear + [3344] = true, -- Kardris Dreamseeker + [16681] = true, -- Champion Bachi + [4568] = true, -- Anastasia Hartwell + [5149] = true, -- Brandur Ironhammer + [376] = true, -- High Priestess Laurena + [5491] = true, -- Arthur the Faithful + [5489] = true, -- Brother Joshua + [4219] = true, -- Fylerian Nightwing + [928] = true, -- Lord Grayson Shadowbreaker + [11401] = true, -- Priestess Alathea + [3401] = true, -- Shenthul + [17219] = true, -- Sulaa + [6018] = true, -- Ur'kyo + [4606] = true, -- Aelthalyste + [17120] = true, -- Behomat + [16653] = true, -- Inethven + [3352] = true, -- Ormak Grimshot + [5144] = true, -- Bink + [5498] = true, -- Elsharin + [17509] = true, -- Jol + [3030] = true, -- Siln Skychaser + [3354] = true, -- Sorek + [5479] = true, -- Wu Shen + [4595] = true, -- Baltus Fowler + [5484] = true, -- Brother Benjamin + [23127] = true, -- Farseer Javad + [5492] = true, -- Katherine the Pure + [5116] = true, -- Olmin Burningbeard + [3407] = true, -- Sian'dur + [4163] = true, -- Syurna + [5147] = true, -- Valgar Highforge + [7312] = true, -- Dink + [20407] = true, -- Farseer Umbrua + [3353] = true, -- Grezz Ragefist + [17520] = true, -- Gurrag + [23128] = true, -- Master Pyreanor + [3041] = true, -- Torm Ragetotem + [16651] = true, -- Zaedana + [5173] = true, -- Alexander Calder + [4582] = true, -- Carolyn Ward + [3039] = true, -- Holt Thunderhorn + [3038] = true, -- Kary Thunderhorn + [3036] = true, -- Kym Wildmane + [13283] = true, -- Lord Tony Romano + [5166] = true, -- Ormyr Flinteye + [16647] = true, -- Talionia + [3033] = true, -- Turak Runetotem + [16771] = true, -- Ahonan + [5148] = true, -- Beldruk Doombrow + [5883] = true, -- Enyo + [17204] = true, -- Farseer Nobundo + [5165] = true, -- Hulfdan Blackbeard + [5145] = true, -- Juli Stormkettle + [16679] = true, -- Osselan + [5171] = true, -- Thistleheart + [5516] = true, -- Ulfir Ironbeard + [3048] = true, -- Ursyn Ghull + [7311] = true, -- Uthel'nay + [5142] = true, -- Braenna Flintcrag + [5172] = true, -- Briarthorn + [7315] = true, -- Darnath Bladesinger + [16749] = true, -- Edirah + [5167] = true, -- Fenthwick + [11406] = true, -- High Priest Rohan + [4566] = true, -- Kaelystia Hatebringer + [4092] = true, -- Lariia + [16659] = true, -- Lotheolan + [4583] = true, -- Miles Dexter + [3325] = true, -- Mirket + [918] = true, -- Osborne the Night Man + [5882] = true, -- Pephredo + [5496] = true, -- Sandahl + [3040] = true, -- Urek Thunderhorn + [5495] = true, -- Ursula Deline + [3406] = true, -- Xor'juul + [16648] = true, -- Zanien + [3047] = true, -- Archmage Shymm + [20406] = true, -- Champion Cyssa Dawnrose + [5115] = true, -- Daera Brightspear + [461] = true, -- Demisette Cloyce + [4608] = true, -- Father Lazarus + [3327] = true, -- Gest + [3324] = true, -- Grol'dar + [16680] = true, -- Ithelis + [4091] = true, -- Jandria + [1901] = true, -- Kelstrum Stonebreaker + [5113] = true, -- Kelv Sternhammer + [17505] = true, -- Killac + [29196] = true, -- Lord Thorval + [4564] = true, -- Luther Pickman + [331] = true, -- Maginor Dumas + [3328] = true, -- Ormok + [4567] = true, -- Pierce Shackleton + [16652] = true, -- Quithas + [5117] = true, -- Regnus Thundergranite + [4565] = true, -- Richard Kerwin + [13417] = true, -- Sagorne Creststrider + [4089] = true, -- Sildanair + [16672] = true, -- Tana + [5505] = true, -- Theridran + [3049] = true, -- Thurston Xane + [3031] = true, -- Tigor Skychaser + [5143] = true, -- Toldren Deepiron + [6014] = true, -- X'yera + [5994] = true, -- Zayus + [914] = true, -- Ander Germaine + [4594] = true, -- Angela Curthas + [4087] = true, -- Arias'ta Bladesinger + [5114] = true, -- Bilban Tosslespanner + [4593] = true, -- Christoph Walker + [4607] = true, -- Father Lankester + [4584] = true, -- Gregory Charles + [5480] = true, -- Ilsa Corbin + [3043] = true, -- Ker Ragetotem + [3045] = true, -- Malakai Cross + [3044] = true, -- Miles Welsh + [16673] = true, -- Oninath + [3042] = true, -- Sark Ragetotem + [3034] = true, -- Sheal Runetotem + [3403] = true, -- Sian'tsu + [3408] = true, -- Zel'mak }, - ["FlightMaster"] = { - 24795, -- Surristrasz - 28037, -- The Spirit of Gnomeregan - 12596, -- Bibilfaz Featherwhistle - 28615, -- Baneflight - 18788, -- Munci - 28574, -- Marvin Wobblesprocket - 33849, -- Helidan Lightwing - 25288, -- Turida Coldwind - 18789, -- Furgu - 29721, -- Skizzle Slickslide - 28618, -- Danica Saint - 29480, -- Grimwing - 11899, -- Shardi - 2226, -- Karos Razok - 8610, -- Kroum - 26881, -- Palena Silvercloud - 2861, -- Gorrik - 23859, -- Greer Orehammer - 30870, -- Herzo Safeflight - 32571, -- Halvdan - 26850, -- Numo Spiritbreeze - 26878, -- Rodney Wells - 352, -- Dungar Longdrink - 30271, -- Galendror Whitewing - 31069, -- Penumbrius - 8609, -- Alexandra Constantine - 2299, -- Borgus Stoutarm - 18808, -- Gursha - 29757, -- Kabarg Windtamer - 26851, -- Nethestrasz - 27046, -- Warmage Adami - 28674, -- Aludane Whitecloud - 28195, -- Bilko Driftspark - 29950, -- Breck Rockbrow - 3841, -- Caylais Moonfeather - 37888, -- Frax Bucketdrop - 2858, -- Gringer - 10583, -- Gryfe - 20515, -- Harpax - 30314, -- Morlia Doomwing - 26876, -- Samuel Clearbook - 6706, -- Baritanas Skyriver - 11900, -- Brakkar - 28196, -- Cid Flounderfix - 3615, -- Devrak - 23612, -- Dyslix Silvergrub - 12636, -- Georgia - 28623, -- Gurric - 4551, -- Michael Garrett - 29951, -- Shavalius the Fancy - 8020, -- Shyn - 30269, -- Skymaster Baeric - 2995, -- Tal - 1572, -- Thorgrum Borrelson - 26879, -- Tomas Riverwell - 12616, -- Vhulgra - 21766, -- Alieshor - 31078, -- Dreadwind - 29750, -- Faldorf Bitterchill - 22216, -- Fhyn Leafshadow - 18807, -- Kerna - 18785, -- Kuma - 523, -- Thor - 18953, -- Unoke Tenderhoof - 30433, -- Aedan Moran - 11901, -- Andruk - 30869, -- Arzo Safeflight - 7823, -- Bera Stonehammer - 18791, -- Du'ga - 8019, -- Fyldren Moonfeather - 24061, -- James Ormsby - 12577, -- Jarrodenus - 26602, -- Kara Thricestar - 23736, -- Pricilla Winterwind - 21107, -- Rip Pedalslam - 17555, -- Stephanos - 18937, -- Amerun Leafshade - 931, -- Ariena Stormfeather - 27344, -- Bat Handler Adeline - 24032, -- Celea Frozenmane - 2432, -- Darla Harris - 26877, -- Derek Rammel - 19317, -- Drek'Gol - 4314, -- Gorkas - 3305, -- Grisha - 8018, -- Guthrum Thunderfist - 2859, -- Gyll - 29762, -- Hyeyoung Parka - 12617, -- Khaelyn Steelwing - 28197, -- Kip Trawlskip - 18938, -- Krexcil - 17554, -- Laando - 11138, -- Maethrya - 18940, -- Nutral - 4317, -- Nyse - 26560, -- Ohura - 30569, -- Rafae - 15178, -- Runk Windtamer - 1571, -- Shellei Brondir - 4407, -- Teloren - 2851, -- Urda - 13177, -- Vahgruk - 11139, -- Yugrek - 4321, -- Baldruc - 16227, -- Bragok - 6026, -- Breyk - 18939, -- Brubeck Stormfoot - 7824, -- Bulkrek Ragefist - 15177, -- Cloud Skydancer - 12740, -- Faustron - 2409, -- Felicia Maline - 16822, -- Flightmaster Krill Bitterhue - 1573, -- Gryth Thurden - 26845, -- Junter Weiss - 26852, -- Kragh - 26844, -- Lilleth Radescu - 19581, -- Maddix - 12578, -- Mishellena - 24366, -- Nizzle - 26847, -- Omu Spiritbreeze - 10378, -- Omusa Thunderhorn - 22935, -- Suralais Farwind - 6726, -- Thalon - 4319, -- Thyssiana - 24155, -- Tobias Sarkhoff - 26880, -- Vana Grey - 3838, -- Vesprystus - 19558, -- Amilya Airheart - 18931, -- Amish Wildhammer - 16587, -- Barley - 2835, -- Cedrik Prose - 4267, -- Daelyshia - 3310, -- Doras - 18809, -- Furnan Skysoar - 22931, -- Gorrim - 19583, -- Grennik - 20762, -- Gur'zil - 22485, -- Halu - 18942, -- Innalia - 26848, -- Kimbiza - 24851, -- Kiz Coilspanner - 2941, -- Lanie Reed - 28624, -- Maaka - 26853, -- Makki Wintergale - 26566, -- Narzun Skybreaker - 20234, -- Runetog Wildhammer - 10897, -- Sindrayl - 22455, -- Sky-Master Maxxor - 16189, -- Skymaster Sunwing - 16192, -- Skymistress Gloaming - 4312, -- Tharm - 1387, -- Thysta - 37915, -- Timothy Cunningham - 18930, -- Vlagga Freyfeather - 2389, -- Zarise + [MINIMAP_TRACKING_FLIGHTMASTER] = { + [24795] = true, -- Surristrasz + [28037] = true, -- The Spirit of Gnomeregan + [12596] = true, -- Bibilfaz Featherwhistle + [28615] = true, -- Baneflight + [18788] = true, -- Munci + [28574] = true, -- Marvin Wobblesprocket + [33849] = true, -- Helidan Lightwing + [25288] = true, -- Turida Coldwind + [18789] = true, -- Furgu + [29721] = true, -- Skizzle Slickslide + [28618] = true, -- Danica Saint + [29480] = true, -- Grimwing + [11899] = true, -- Shardi + [2226] = true, -- Karos Razok + [8610] = true, -- Kroum + [26881] = true, -- Palena Silvercloud + [2861] = true, -- Gorrik + [23859] = true, -- Greer Orehammer + [30870] = true, -- Herzo Safeflight + [32571] = true, -- Halvdan + [26850] = true, -- Numo Spiritbreeze + [26878] = true, -- Rodney Wells + [352] = true, -- Dungar Longdrink + [30271] = true, -- Galendror Whitewing + [31069] = true, -- Penumbrius + [8609] = true, -- Alexandra Constantine + [2299] = true, -- Borgus Stoutarm + [18808] = true, -- Gursha + [29757] = true, -- Kabarg Windtamer + [26851] = true, -- Nethestrasz + [27046] = true, -- Warmage Adami + [28674] = true, -- Aludane Whitecloud + [28195] = true, -- Bilko Driftspark + [29950] = true, -- Breck Rockbrow + [3841] = true, -- Caylais Moonfeather + [37888] = true, -- Frax Bucketdrop + [2858] = true, -- Gringer + [10583] = true, -- Gryfe + [20515] = true, -- Harpax + [30314] = true, -- Morlia Doomwing + [26876] = true, -- Samuel Clearbook + [6706] = true, -- Baritanas Skyriver + [11900] = true, -- Brakkar + [28196] = true, -- Cid Flounderfix + [3615] = true, -- Devrak + [23612] = true, -- Dyslix Silvergrub + [12636] = true, -- Georgia + [28623] = true, -- Gurric + [4551] = true, -- Michael Garrett + [29951] = true, -- Shavalius the Fancy + [8020] = true, -- Shyn + [30269] = true, -- Skymaster Baeric + [2995] = true, -- Tal + [1572] = true, -- Thorgrum Borrelson + [26879] = true, -- Tomas Riverwell + [12616] = true, -- Vhulgra + [21766] = true, -- Alieshor + [31078] = true, -- Dreadwind + [29750] = true, -- Faldorf Bitterchill + [22216] = true, -- Fhyn Leafshadow + [18807] = true, -- Kerna + [18785] = true, -- Kuma + [523] = true, -- Thor + [18953] = true, -- Unoke Tenderhoof + [30433] = true, -- Aedan Moran + [11901] = true, -- Andruk + [30869] = true, -- Arzo Safeflight + [7823] = true, -- Bera Stonehammer + [18791] = true, -- Du'ga + [8019] = true, -- Fyldren Moonfeather + [24061] = true, -- James Ormsby + [12577] = true, -- Jarrodenus + [26602] = true, -- Kara Thricestar + [23736] = true, -- Pricilla Winterwind + [21107] = true, -- Rip Pedalslam + [17555] = true, -- Stephanos + [18937] = true, -- Amerun Leafshade + [931] = true, -- Ariena Stormfeather + [27344] = true, -- Bat Handler Adeline + [24032] = true, -- Celea Frozenmane + [2432] = true, -- Darla Harris + [26877] = true, -- Derek Rammel + [19317] = true, -- Drek'Gol + [4314] = true, -- Gorkas + [3305] = true, -- Grisha + [8018] = true, -- Guthrum Thunderfist + [2859] = true, -- Gyll + [29762] = true, -- Hyeyoung Parka + [12617] = true, -- Khaelyn Steelwing + [28197] = true, -- Kip Trawlskip + [18938] = true, -- Krexcil + [17554] = true, -- Laando + [11138] = true, -- Maethrya + [18940] = true, -- Nutral + [4317] = true, -- Nyse + [26560] = true, -- Ohura + [30569] = true, -- Rafae + [15178] = true, -- Runk Windtamer + [1571] = true, -- Shellei Brondir + [4407] = true, -- Teloren + [2851] = true, -- Urda + [13177] = true, -- Vahgruk + [11139] = true, -- Yugrek + [4321] = true, -- Baldruc + [16227] = true, -- Bragok + [6026] = true, -- Breyk + [18939] = true, -- Brubeck Stormfoot + [7824] = true, -- Bulkrek Ragefist + [15177] = true, -- Cloud Skydancer + [12740] = true, -- Faustron + [2409] = true, -- Felicia Maline + [16822] = true, -- Flightmaster Krill Bitterhue + [1573] = true, -- Gryth Thurden + [26845] = true, -- Junter Weiss + [26852] = true, -- Kragh + [26844] = true, -- Lilleth Radescu + [19581] = true, -- Maddix + [12578] = true, -- Mishellena + [24366] = true, -- Nizzle + [26847] = true, -- Omu Spiritbreeze + [10378] = true, -- Omusa Thunderhorn + [22935] = true, -- Suralais Farwind + [6726] = true, -- Thalon + [4319] = true, -- Thyssiana + [24155] = true, -- Tobias Sarkhoff + [26880] = true, -- Vana Grey + [3838] = true, -- Vesprystus + [19558] = true, -- Amilya Airheart + [18931] = true, -- Amish Wildhammer + [16587] = true, -- Barley + [2835] = true, -- Cedrik Prose + [4267] = true, -- Daelyshia + [3310] = true, -- Doras + [18809] = true, -- Furnan Skysoar + [22931] = true, -- Gorrim + [19583] = true, -- Grennik + [20762] = true, -- Gur'zil + [22485] = true, -- Halu + [18942] = true, -- Innalia + [26848] = true, -- Kimbiza + [24851] = true, -- Kiz Coilspanner + [2941] = true, -- Lanie Reed + [28624] = true, -- Maaka + [26853] = true, -- Makki Wintergale + [26566] = true, -- Narzun Skybreaker + [20234] = true, -- Runetog Wildhammer + [10897] = true, -- Sindrayl + [22455] = true, -- Sky-Master Maxxor + [16189] = true, -- Skymaster Sunwing + [16192] = true, -- Skymistress Gloaming + [4312] = true, -- Tharm + [1387] = true, -- Thysta + [37915] = true, -- Timothy Cunningham + [18930] = true, -- Vlagga Freyfeather + [2389] = true, -- Zarise }, - ["Innkeeper"] = { - 28687, -- Amisi Azuregaze - 32413, -- Isirami Fairwind - 16826, -- Sid Limbardi - 15174, -- Calandrath - 16602, -- Floyd Pinkus - 19296, -- Innkeeper Biribi - 29532, -- Ajay Green - 31557, -- Uda the Beast - 18957, -- Innkeeper Grilka - 6740, -- Innkeeper Allison - 6746, -- Innkeeper Pala - 6735, -- Innkeeper Saelienne - 18906, -- Caregiver Ophera Windfury - 18907, -- Innkeeper Coryth Stoktron - 6741, -- Innkeeper Norman - 7736, -- Innkeeper Shyria - 32418, -- Abohba - 1247, -- Innkeeper Belm - 6790, -- Innkeeper Trelayne - 24342, -- Timothy Holland - 6739, -- Innkeeper Bates - 295, -- Innkeeper Farley - 6734, -- Innkeeper Hearthstove - 25278, -- Williamson - 18914, -- Caregiver Isel - 7733, -- Innkeeper Fizzgrimble - 11103, -- Innkeeper Lyshaerya - 15397, -- Marniel Amberlight - 28038, -- Purser Boulian - 18251, -- Caregiver Abidaar - 30308, -- Initiate Brenners - 11116, -- Innkeeper Abeqwa - 3934, -- Innkeeper Boorand Plainswind - 18908, -- Innkeeper Kerp - 16256, -- Jessica Chambers - 26709, -- Pahu Frosthoof - 29583, -- Pan'ya - 16739, -- Caregiver Breel - 27187, -- Caregiver Poallu - 24057, -- Christina Daniels - 23937, -- Innkeeper Celeste Goodhutch - 19232, -- Innkeeper Haelthol - 6736, -- Innkeeper Keldamyr - 11106, -- Innkeeper Sikewa - 21744, -- Roldemar - 24208, -- "Little" Logok - 26680, -- Aiyan Coldwind - 26985, -- Barracks Master Harga - 27125, -- Barracks Master Rhekku - 27174, -- Caregiver Mumik - 8931, -- Innkeeper Heather - 1464, -- Innkeeper Helbrek - 19495, -- Innkeeper Shaunessy - 2388, -- Innkeeper Shay - 7744, -- Innkeeper Thulfram - 19046, -- Minalei - 29971, -- Wabada Whiteflower - 26596, -- "Charlie" Northtop - 27148, -- Caregiver Iqniq - 33970, -- Caris Sunlance - 21110, -- Fizit "Doc" Clocktock - 22922, -- Innkeeper Aelerya - 5111, -- Innkeeper Firebrew - 23731, -- Innkeeper Hazel Lagras - 17630, -- Innkeeper Jovia - 6747, -- Innkeeper Kauth - 16618, -- Innkeeper Velandra - 25245, -- James Deacon - 30005, -- Lodge-Matron Embla - 29963, -- Magorn - 21088, -- Matron Varah - 29904, -- Smilin' Slirk Brassknob - 32411, -- Afsaneh Asrar - 23995, -- Axle - 24033, -- Bori Wintertotem - 25036, -- Caregiver Inaara - 27950, -- Demestrasz - 19352, -- Dreg Cloudsweeper - 19531, -- Eyonix - 19470, -- Gholah - 29926, -- Gunda Boldhammer - 27042, -- Illusia Lune - 18905, -- Innkeeper Bazil Olof'tazun - 6727, -- Innkeeper Brianna - 7714, -- Innkeeper Byula - 6272, -- Innkeeper Janene - 6930, -- Innkeeper Karakul - 12196, -- Innkeeper Kaylisk - 6738, -- Innkeeper Kimlya - 19571, -- Innkeeper Remi Dodoso - 5688, -- Innkeeper Renee - 9356, -- Innkeeper Shul'kar - 5814, -- Innkeeper Thulbek - 11118, -- Innkeeper Vizzie - 33971, -- Jarin Dawnglow - 18913, -- Matron Tikkit - 27052, -- Naohain - 29944, -- Peon Gakra - 26375, -- Quartermaster McCarty - 24149, -- Basil Osgood - 28686, -- Caliel Brightwillow - 16553, -- Caregiver Chellan - 17553, -- Caregiver Topher Loaal - 21746, -- Caretaker Aluuro - 9501, -- Innkeeper Adegwa - 2352, -- Innkeeper Anderson - 19319, -- Innkeeper Darg Bloodclaw - 15433, -- Innkeeper Delaniel - 16458, -- Innkeeper Faralia - 7737, -- Innkeeper Greul - 6928, -- Innkeeper Grosk - 6929, -- Innkeeper Gryshka - 7731, -- Innkeeper Jayka - 16542, -- Innkeeper Kalarin - 6737, -- Innkeeper Shaussiy - 6807, -- Innkeeper Skindle - 6791, -- Innkeeper Wiley - 27066, -- Jennifer Bell - 14731, -- Lard - 28791, -- Marissa Everwatch - 27069, -- Matron Magah - 18245, -- Merajit - 27027, -- Mrs. Winterby + [MINIMAP_TRACKING_INNKEEPER] = { + [28687] = true, -- Amisi Azuregaze + [32413] = true, -- Isirami Fairwind + [16826] = true, -- Sid Limbardi + [15174] = true, -- Calandrath + [16602] = true, -- Floyd Pinkus + [19296] = true, -- Innkeeper Biribi + [29532] = true, -- Ajay Green + [31557] = true, -- Uda the Beast + [18957] = true, -- Innkeeper Grilka + [6740] = true, -- Innkeeper Allison + [6746] = true, -- Innkeeper Pala + [6735] = true, -- Innkeeper Saelienne + [18906] = true, -- Caregiver Ophera Windfury + [18907] = true, -- Innkeeper Coryth Stoktron + [6741] = true, -- Innkeeper Norman + [7736] = true, -- Innkeeper Shyria + [32418] = true, -- Abohba + [1247] = true, -- Innkeeper Belm + [6790] = true, -- Innkeeper Trelayne + [24342] = true, -- Timothy Holland + [6739] = true, -- Innkeeper Bates + [295] = true, -- Innkeeper Farley + [6734] = true, -- Innkeeper Hearthstove + [25278] = true, -- Williamson + [18914] = true, -- Caregiver Isel + [7733] = true, -- Innkeeper Fizzgrimble + [11103] = true, -- Innkeeper Lyshaerya + [15397] = true, -- Marniel Amberlight + [28038] = true, -- Purser Boulian + [18251] = true, -- Caregiver Abidaar + [30308] = true, -- Initiate Brenners + [11116] = true, -- Innkeeper Abeqwa + [3934] = true, -- Innkeeper Boorand Plainswind + [18908] = true, -- Innkeeper Kerp + [16256] = true, -- Jessica Chambers + [26709] = true, -- Pahu Frosthoof + [29583] = true, -- Pan'ya + [16739] = true, -- Caregiver Breel + [27187] = true, -- Caregiver Poallu + [24057] = true, -- Christina Daniels + [23937] = true, -- Innkeeper Celeste Goodhutch + [19232] = true, -- Innkeeper Haelthol + [6736] = true, -- Innkeeper Keldamyr + [11106] = true, -- Innkeeper Sikewa + [21744] = true, -- Roldemar + [24208] = true, -- "Little" Logok + [26680] = true, -- Aiyan Coldwind + [26985] = true, -- Barracks Master Harga + [27125] = true, -- Barracks Master Rhekku + [27174] = true, -- Caregiver Mumik + [8931] = true, -- Innkeeper Heather + [1464] = true, -- Innkeeper Helbrek + [19495] = true, -- Innkeeper Shaunessy + [2388] = true, -- Innkeeper Shay + [7744] = true, -- Innkeeper Thulfram + [19046] = true, -- Minalei + [29971] = true, -- Wabada Whiteflower + [26596] = true, -- "Charlie" Northtop + [27148] = true, -- Caregiver Iqniq + [33970] = true, -- Caris Sunlance + [21110] = true, -- Fizit "Doc" Clocktock + [22922] = true, -- Innkeeper Aelerya + [5111] = true, -- Innkeeper Firebrew + [23731] = true, -- Innkeeper Hazel Lagras + [17630] = true, -- Innkeeper Jovia + [6747] = true, -- Innkeeper Kauth + [16618] = true, -- Innkeeper Velandra + [25245] = true, -- James Deacon + [30005] = true, -- Lodge-Matron Embla + [29963] = true, -- Magorn + [21088] = true, -- Matron Varah + [29904] = true, -- Smilin' Slirk Brassknob + [32411] = true, -- Afsaneh Asrar + [23995] = true, -- Axle + [24033] = true, -- Bori Wintertotem + [25036] = true, -- Caregiver Inaara + [27950] = true, -- Demestrasz + [19352] = true, -- Dreg Cloudsweeper + [19531] = true, -- Eyonix + [19470] = true, -- Gholah + [29926] = true, -- Gunda Boldhammer + [27042] = true, -- Illusia Lune + [18905] = true, -- Innkeeper Bazil Olof'tazun + [6727] = true, -- Innkeeper Brianna + [7714] = true, -- Innkeeper Byula + [6272] = true, -- Innkeeper Janene + [6930] = true, -- Innkeeper Karakul + [12196] = true, -- Innkeeper Kaylisk + [6738] = true, -- Innkeeper Kimlya + [19571] = true, -- Innkeeper Remi Dodoso + [5688] = true, -- Innkeeper Renee + [9356] = true, -- Innkeeper Shul'kar + [5814] = true, -- Innkeeper Thulbek + [11118] = true, -- Innkeeper Vizzie + [33971] = true, -- Jarin Dawnglow + [18913] = true, -- Matron Tikkit + [27052] = true, -- Naohain + [29944] = true, -- Peon Gakra + [26375] = true, -- Quartermaster McCarty + [24149] = true, -- Basil Osgood + [28686] = true, -- Caliel Brightwillow + [16553] = true, -- Caregiver Chellan + [17553] = true, -- Caregiver Topher Loaal + [21746] = true, -- Caretaker Aluuro + [9501] = true, -- Innkeeper Adegwa + [2352] = true, -- Innkeeper Anderson + [19319] = true, -- Innkeeper Darg Bloodclaw + [15433] = true, -- Innkeeper Delaniel + [16458] = true, -- Innkeeper Faralia + [7737] = true, -- Innkeeper Greul + [6928] = true, -- Innkeeper Grosk + [6929] = true, -- Innkeeper Gryshka + [7731] = true, -- Innkeeper Jayka + [16542] = true, -- Innkeeper Kalarin + [6737] = true, -- Innkeeper Shaussiy + [6807] = true, -- Innkeeper Skindle + [6791] = true, -- Innkeeper Wiley + [27066] = true, -- Jennifer Bell + [14731] = true, -- Lard + [28791] = true, -- Marissa Everwatch + [27069] = true, -- Matron Magah + [18245] = true, -- Merajit + [27027] = true, -- Mrs. Winterby }, - ["Reagents"] = { - 1257, -- Keldric Boucher - 3323, -- Horthus - 29537, -- Darahir - 3562, -- Alaindia - 24780, -- Field Repair Bot 110G - 3335, -- Hagrus - 16015, -- Vi'el - 25082, -- Engineer Torquespindle - 25039, -- Kaalif - 24935, -- Vend-O-Tron D-Luxe - 19679, -- "Slim" - 27133, -- Seer Yagnar - 28809, -- Vincent Huber - 30345, -- Chief Engineer Boltwrench - 1463, -- Falkan Armonis - 3490, -- Hula'mahi - 4575, -- Hannah Akeley - 19718, -- Provisioner Tsaalt - 26474, -- Ameenah - 26968, -- Drikka - 26984, -- Stephan Franks - 27138, -- Apprentice Rosen - 28827, -- Co'man - 4220, -- Cyroen - 35642, -- Jeeves - 4878, -- Montarr - 19678, -- Fantei - 24349, -- Jessica Evans - 27149, -- Arrluk - 983, -- Thultazor - 2805, -- Deneb Walker - 14739, -- Mystic Yayo'jin - 19013, -- Vanteg - 19535, -- Dealer Zijaad - 20915, -- Noko Moonwhisper - 30010, -- Fylla Ingadottir - 1307, -- Charys Yserian - 3542, -- Jaysin Lanyda - 3700, -- Jadenvis Seawatcher - 8361, -- Chepi - 16706, -- Musal - 16829, -- Magus Zabraxis - 23145, -- Rumpus - 23157, -- Aluyen - 24357, -- Maethor Skyshadow - 24396, -- Forest Frog - 25736, -- Supply Master Taz'ishi - 26908, -- Helen Fairchild - 30069, -- Initiate Roderick - 30244, -- Miura Brightweaver - 37935, -- Apothecary Candith Tomas - 3351, -- Magenius - 27030, -- Bradley Towns - 29288, -- Engineer Kurtis Paddock - 29961, -- Brangrimm - 33669, -- Demolisher Engineer Blastwrench - 1351, -- Brother Cassius - 1673, -- Alyssa Eva - 18243, -- Lorti - 18998, -- Lursa Sunfallow - 19004, -- Vodesiin - 19235, -- Amshesha Stilldark - 25019, -- Merchant Felagunne - 26598, -- Mistie Flitterdawn - 26900, -- Tinky Stabberson - 27176, -- Mystic Makittuq - 27935, -- Ferithos - 28870, -- Corpsedust - 30239, -- Alanura Firecloud - 30438, -- Supply Officer Thalmers - 37904, -- Brazie Getz - 1275, -- Kyra Boucher - 3500, -- Tarhus - 4562, -- Thomas Mordan - 18017, -- Seer Janidi - 19014, -- Ogir - 24995, -- Merchant Fallel Stargazer - 26382, -- Balfour Blackblade - 27039, -- Lexey Brevig - 29015, -- Shaman Partak - 29037, -- Soo-jam - 29909, -- Nilika Blastbeaker - 29922, -- Corig the Cunning - 30307, -- Sarhule the Risen - 32639, -- Gnimo - 33871, -- Julie Osworth - 3970, -- Llana - 5110, -- Barim Jurgenstaad - 17518, -- Ythyar - 18019, -- Timothy Daniels - 23373, -- Mortog Steamhead - 23560, -- Provisioner Ameenah - 24409, -- Kyren - 25010, -- Engineer Brightbuckle - 27186, -- Oogrooq - 29968, -- Hapanu Coldwind - 30825, -- Chief Engineer Copperclaw - 32641, -- Drix Blackwrench - 12097, -- Frostwolf Quartermaster - 15175, -- Khur Hornstriker - 16611, -- Zalle - 16612, -- Velanni - 16757, -- Bildine - 20081, -- Bortega - 25051, -- Merchant Frostwalker - 26569, -- Alys Vol'tyr - 27088, -- Yolanda Haymer - 28714, -- Ildine Sorrowspear - 29203, -- Alchemist Karloff - 31115, -- Quartermaster Vaskess - 958, -- Dawn Brightstar - 1308, -- Owen Vaughn - 4083, -- Jeeda - 5139, -- Kurdrum Barleybeard - 5151, -- Ginny Longberry - 10364, -- Yaelika Farclaw - 12096, -- Stormpike Quartermaster - 13476, -- Balai Lok'Wein - 18006, -- Noraani - 20092, -- Dealer Hazzin - 22479, -- Sab'aoth - 23112, -- Mingo - 24313, -- Celina Summers - 24843, -- Engineer Combs - 26950, -- Sanut Swiftspear - 27054, -- Modoru - 29561, -- Scrapbot - 29636, -- Hagatha Moorehead - 29947, -- Apothecary Maple + [MINIMAP_TRACKING_VENDOR_REAGENT] = { + [1257] = true, -- Keldric Boucher + [3323] = true, -- Horthus + [29537] = true, -- Darahir + [3562] = true, -- Alaindia + [24780] = true, -- Field Repair Bot [110] = trueG + [3335] = true, -- Hagrus + [16015] = true, -- Vi'el + [25082] = true, -- Engineer Torquespindle + [25039] = true, -- Kaalif + [24935] = true, -- Vend-O-Tron D-Luxe + [19679] = true, -- "Slim" + [27133] = true, -- Seer Yagnar + [28809] = true, -- Vincent Huber + [30345] = true, -- Chief Engineer Boltwrench + [1463] = true, -- Falkan Armonis + [3490] = true, -- Hula'mahi + [4575] = true, -- Hannah Akeley + [19718] = true, -- Provisioner Tsaalt + [26474] = true, -- Ameenah + [26968] = true, -- Drikka + [26984] = true, -- Stephan Franks + [27138] = true, -- Apprentice Rosen + [28827] = true, -- Co'man + [4220] = true, -- Cyroen + [35642] = true, -- Jeeves + [4878] = true, -- Montarr + [19678] = true, -- Fantei + [24349] = true, -- Jessica Evans + [27149] = true, -- Arrluk + [983] = true, -- Thultazor + [2805] = true, -- Deneb Walker + [14739] = true, -- Mystic Yayo'jin + [19013] = true, -- Vanteg + [19535] = true, -- Dealer Zijaad + [20915] = true, -- Noko Moonwhisper + [30010] = true, -- Fylla Ingadottir + [1307] = true, -- Charys Yserian + [3542] = true, -- Jaysin Lanyda + [3700] = true, -- Jadenvis Seawatcher + [8361] = true, -- Chepi + [16706] = true, -- Musal + [16829] = true, -- Magus Zabraxis + [23145] = true, -- Rumpus + [23157] = true, -- Aluyen + [24357] = true, -- Maethor Skyshadow + [24396] = true, -- Forest Frog + [25736] = true, -- Supply Master Taz'ishi + [26908] = true, -- Helen Fairchild + [30069] = true, -- Initiate Roderick + [30244] = true, -- Miura Brightweaver + [37935] = true, -- Apothecary Candith Tomas + [3351] = true, -- Magenius + [27030] = true, -- Bradley Towns + [29288] = true, -- Engineer Kurtis Paddock + [29961] = true, -- Brangrimm + [33669] = true, -- Demolisher Engineer Blastwrench + [1351] = true, -- Brother Cassius + [1673] = true, -- Alyssa Eva + [18243] = true, -- Lorti + [18998] = true, -- Lursa Sunfallow + [19004] = true, -- Vodesiin + [19235] = true, -- Amshesha Stilldark + [25019] = true, -- Merchant Felagunne + [26598] = true, -- Mistie Flitterdawn + [26900] = true, -- Tinky Stabberson + [27176] = true, -- Mystic Makittuq + [27935] = true, -- Ferithos + [28870] = true, -- Corpsedust + [30239] = true, -- Alanura Firecloud + [30438] = true, -- Supply Officer Thalmers + [37904] = true, -- Brazie Getz + [1275] = true, -- Kyra Boucher + [3500] = true, -- Tarhus + [4562] = true, -- Thomas Mordan + [18017] = true, -- Seer Janidi + [19014] = true, -- Ogir + [24995] = true, -- Merchant Fallel Stargazer + [26382] = true, -- Balfour Blackblade + [27039] = true, -- Lexey Brevig + [29015] = true, -- Shaman Partak + [29037] = true, -- Soo-jam + [29909] = true, -- Nilika Blastbeaker + [29922] = true, -- Corig the Cunning + [30307] = true, -- Sarhule the Risen + [32639] = true, -- Gnimo + [33871] = true, -- Julie Osworth + [3970] = true, -- Llana + [5110] = true, -- Barim Jurgenstaad + [17518] = true, -- Ythyar + [18019] = true, -- Timothy Daniels + [23373] = true, -- Mortog Steamhead + [23560] = true, -- Provisioner Ameenah + [24409] = true, -- Kyren + [25010] = true, -- Engineer Brightbuckle + [27186] = true, -- Oogrooq + [29968] = true, -- Hapanu Coldwind + [30825] = true, -- Chief Engineer Copperclaw + [32641] = true, -- Drix Blackwrench + [12097] = true, -- Frostwolf Quartermaster + [15175] = true, -- Khur Hornstriker + [16611] = true, -- Zalle + [16612] = true, -- Velanni + [16757] = true, -- Bildine + [20081] = true, -- Bortega + [25051] = true, -- Merchant Frostwalker + [26569] = true, -- Alys Vol'tyr + [27088] = true, -- Yolanda Haymer + [28714] = true, -- Ildine Sorrowspear + [29203] = true, -- Alchemist Karloff + [31115] = true, -- Quartermaster Vaskess + [958] = true, -- Dawn Brightstar + [1308] = true, -- Owen Vaughn + [4083] = true, -- Jeeda + [5139] = true, -- Kurdrum Barleybeard + [5151] = true, -- Ginny Longberry + [10364] = true, -- Yaelika Farclaw + [12096] = true, -- Stormpike Quartermaster + [13476] = true, -- Balai Lok'Wein + [18006] = true, -- Noraani + [20092] = true, -- Dealer Hazzin + [22479] = true, -- Sab'aoth + [23112] = true, -- Mingo + [24313] = true, -- Celina Summers + [24843] = true, -- Engineer Combs + [26950] = true, -- Sanut Swiftspear + [27054] = true, -- Modoru + [29561] = true, -- Scrapbot + [29636] = true, -- Hagatha Moorehead + [29947] = true, -- Apothecary Maple }, - ["Repair"] = { - 19373, -- Mari Stonehand - 28995, -- Paldesse - 16583, -- Rohok - 34252, -- Dubin Clay - 28992, -- Valerie Langrom - 37687, -- Alchemist Finklestein - 29523, -- Bragund Brightlink - 28997, -- Griselda Hunderland - 25206, -- Ahlurglgr - 31863, -- Nargle Lashcord - 35496, -- Rueben Lauren - 35498, -- Horace Hunderland - 23381, -- Tydormu - 38316, -- Ormus the Penitent - 17904, -- Fedryen Swiftspear - 28040, -- Mardan Thunderhoof - 3392, -- Prospector Khazgorm - 35497, -- Rafael Langrom - 14624, -- Master Smith Burninate - 18011, -- Zurai - 35500, -- Matilda Brightlink - 38858, -- Goodman the "Closer" - 8161, -- Harggan - 19662, -- Aaron Hollman - 19575, -- Qiff - 34087, -- Trapjaw Rix - 38283, -- Malfus Grimfrost - 18382, -- Mycah - 31864, -- Xazi Smolderpipe - 14754, -- Kelm Hargunth - 12788, -- Legionnaire Teena - 14921, -- Rin'wosho the Trader - 19383, -- Captured Gnome - 33594, -- Fizzix Blastbolt - 12778, -- Lieutenant Rachel Vaccar - 32385, -- Doris Volanthius - 30006, -- Warsmith Sigfinna - 19536, -- Dealer Jadyan - 28722, -- Bryan Landers - 37696, -- Crusader Halford - 3322, -- Kaja - 7852, -- Pratt McGrubben - 29494, -- Shen Kang Cheng - 29014, -- Grakjek - 14753, -- Illiyana Moonblaze - 28990, -- Anthony Durain - 32381, -- Captain Dirgehammer - 8176, -- Gharash - 27037, -- Hidetrader Jun'ik - 16631, -- Andra - 31781, -- Blast Thunderbomb - 11278, -- Magnus Frostwake - 37998, -- Talan Moonstrike - 32834, -- Knight-Lieutenant Moonstrike - 28500, -- Master Siegesmith Corvus - 37992, -- Tortunok - 32832, -- Blood Guard Zar'shi - 16376, -- Craftsman Wilhelm - 1669, -- Defias Profiteer - 3682, -- Vrang Wildgore - 1298, -- Frederick Stover - 15289, -- Raelis Dawnstar - 31865, -- Zom Bocom - 10857, -- Argent Quartermaster Lightspark - 12782, -- Captain O'Neal - 31776, -- Frazzle Geargrinder - 9179, -- Jazzrik - 20242, -- Karaaz - 15126, -- Rutherford Twing - 27011, -- Broff Bombast - 29688, -- Engineer Reed - 25314, -- Archmage Berinand - 37688, -- Crusader Grimtong - 15909, -- Fariel Starsong - 26081, -- High Admiral "Shelly" Jorrik - 3319, -- Sana - 15176, -- Vargus - 37999, -- Alana Moonstrike - 15292, -- Faraden Thelryn - 37993, -- Gerardo the Suave - 5170, -- Hjoldir Stoneblade - 3589, -- Keina - 21183, -- Oronok Torn-heart - 14581, -- Sergeant Thunderhorn - 3534, -- Wallace the Blind - 3167, -- Wuark - 32594, -- Calder - 38181, -- Haragg the Unseen - 19342, -- Krek Cragcrush - 19011, -- Osrok the Immovable - 23007, -- Paulsta'ats - 38054, -- Scott the Merciful - 25046, -- Smith Hauthaa - 13217, -- Thanthaldis Snowgleam - 3314, -- Urtharo - 38284, -- Uvlus Banefire - 28991, -- Valaden Silverblade - 29907, -- Xark Bolthammer - 3537, -- Zixil - 2135, -- Abe Winters - 228, -- Avette Fellwood - 3951, -- Bhaldaran Ravenshade - 28344, -- Blazzle - 1687, -- Cliff Hadin - 19526, -- Dunaman - 30434, -- Durik Bronzebomb - 23367, -- Grella - 16823, -- Humphry - 2844, -- Hurklor - 2843, -- Jutak - 5411, -- Krinkle Goodsteel - 12942, -- Leonard Porter - 3529, -- Moonrage Armorer - 1645, -- Quartermaster Hicks - 32383, -- Sergeant Thunderhorn - 20231, -- Supply Officer Pestle - 28989, -- Aemara - 8131, -- Blizrik Buckshot - 1450, -- Brahnmar - 21474, -- Coreiel - 4164, -- Cylania - 27943, -- Dalormi - 1686, -- Irene Sureshot - 29252, -- Jason Riggins - 16918, -- Jel - 19047, -- Lissaf - 29945, -- Marksman Udabu - 3539, -- Ott - 28716, -- Palja Amboss - 24188, -- Samuel Rosemond - 14737, -- Smith Slagtree - 1690, -- Thrawn Boltar - 3349, -- Ukra'nor - 16637, -- Welethelon - 2679, -- Wenna Silkbeard - 19517, -- Alorra - 20613, -- Arodis Sunblade - 16715, -- Avelii - 17667, -- Beega - 4602, -- Benijah Fenner - 14301, -- Brinna Valanaar - 26600, -- Chief Engineer Galpen Rolltie - 1314, -- Duncan Cullen - 13216, -- Gaelden Hammersmith - 3343, -- Grelkor - 13218, -- Grunnda Wolfheart - 30067, -- Initiate Claget - 13219, -- Jekyll Flandring - 3015, -- Kuna Thunderhorn - 74, -- Kurran Steele - 19520, -- Lelagar - 4177, -- Melea - 38182, -- Niby the Almighty - 16528, -- Provisioner Vredigar - 5108, -- Raena Flinthammer - 19240, -- Selanam the Blade - 18672, -- Thomas Yance - 19238, -- Urumir Stavebright - 38841, -- Vol'guk - 22099, -- Wyrmcult Provisioner - 2482, -- Zarena Cromwind - 3409, -- Zendo'jian - 20917, -- Zinyen Swiftstrider - 1214, -- Aldren Cordon - 3592, -- Andiss - 27667, -- Anwehu - 1312, -- Ardwyn Cailen - 10856, -- Argent Quartermaster Hasana - 28796, -- Arlen Brighthammer - 29499, -- Bartram Haller - 1240, -- Boran Ironclink - 12777, -- Captain Dirgehammer - 29964, -- Dargum Hammerdeep - 14337, -- Field Repair Bot 74A - 3080, -- Harant Ironbrace - 28760, -- Hargus the Geist - 29538, -- Hexil Garrot - 3160, -- Huklah - 5155, -- Ingrys Stonebrow - 15291, -- Jainthess Thelryn - 12023, -- Kharedon - 12792, -- Lady Palanseer - 4558, -- Lauren Newcomb - 27139, -- Librarian Whitley - 4186, -- Mavralyn - 3533, -- Moonrage Leatherworker - 167, -- Morhan Coppertongue - 8878, -- Muuran - 4085, -- Nizzik - 16691, -- Noraelath - 22264, -- Ogri'la Steelshaper - 17412, -- Phaedra - 3528, -- Pyrewood Armorer - 3532, -- Pyrewood Leatherworker - 2849, -- Qixdi Goodstitch - 3543, -- Robert Aebischer - 27134, -- Smith Prigka - 9551, -- Starn - 18426, -- Terellia - 1668, -- William MacGregor - 37997, -- Yili - 9544, -- Yuka Screwspigot - 21485, -- Aldraan - 25274, -- Armorer Orkuruk - 20616, -- Asuur - 22476, -- Aundro - 16917, -- Aurok - 23735, -- Bartleby Armorfist - 3611, -- Brannol Eaglemoon - 4240, -- Caynrus - 16619, -- Celana - 27151, -- Deniigi - 190, -- Dermot Johns - 836, -- Durnan Furcutter - 4180, -- Ealyshia Dewwhisper - 28813, -- Elizabeth Hollingsworth - 28943, -- Fineous - 1698, -- Frast Dokner - 3591, -- Freja Nightwing - 4184, -- Geenia Sunshadow - 19333, -- Grokom Deatheye - 1289, -- Gunther Weller - 19879, -- Horvon the Armorer - 3491, -- Ironzar - 2847, -- Jansen Underwood - 3410, -- Jin'sora - 5512, -- Kaita Deepforge - 3021, -- Kard Ragetotem - 954, -- Kat Sampson - 4257, -- Lana Thunderbrew - 29035, -- Loomee - 18010, -- Maktu - 22227, -- Markus Scylan - 27045, -- Master Smith Devin Brevig - 4171, -- Merelyssa - 3613, -- Meri Ironweave - 3531, -- Moonrage Tailor - 16919, -- Mura - 9553, -- Nadia Vernon - 16274, -- Narina - 4603, -- Nicholas Atwood - 12805, -- Officer Areyn - 27267, -- Quartermaster Bartlett - 30336, -- Runesmith Balehammer - 16261, -- Sathiel - 12799, -- Sergeant Ba'sha - 37903, -- Shely Steelbowels - 3361, -- Shoma - 27019, -- Siegesmith Gulda - 19315, -- Supply Officer Isabel - 19314, -- Supply Officer Shandria - 19001, -- Talaara - 26697, -- Tewah Chillmane - 26229, -- Tiernan Anvilheart - 26898, -- Troz - 4086, -- Veenix - 4604, -- Abigail Sawyer - 1349, -- Agustus Moulaine - 19043, -- Ahemen - 1294, -- Aldric Moore - 20463, -- Apprentice Andrethan - 15400, -- Arathel Sunforge - 17655, -- Blacksmith Frances - 3162, -- Burdrak Harglhelm - 9548, -- Cawind Trueaim - 32477, -- Chester Copperpot - 4236, -- Cyridan - 19351, -- Daggle Ironshaper - 29923, -- Dagni Oregleam - 27067, -- Drigoth - 8360, -- Elki - 16765, -- Ellomin - 16258, -- Farsil - 16666, -- Feledis - 4043, -- Galthuk - 1238, -- Gamili Frosthide - 5820, -- Gillian Moore - 1362, -- Gothor Brumn - 1348, -- Gregory Ardus - 1104, -- Grundel Harkin - 10361, -- Gruul Darkblade - 5133, -- Harick Boulderdrum - 981, -- Hartash - 2483, -- Jaquilina Dramet - 4892, -- Jensen Farran - 793, -- Kara Adams - 5509, -- Kathrum Axehand - 5121, -- Kelomir Ironhand - 3588, -- Khardan Proudblade - 3360, -- Koru - 3536, -- Kris Legace - 30241, -- Lanudal Silverhart - 12784, -- Lieutenant Jackspring - 1297, -- Lina Stover - 1299, -- Lisbeth Schneider - 5156, -- Maeva Snowbraid - 37936, -- Morgan Dayblaze - 959, -- Morley Eberlein - 16735, -- Muhaa - 222, -- Nillen Andemar - 30572, -- Nofal - 8398, -- Ohanko - 23159, -- Okuno - 1323, -- Osric Strang - 1249, -- Quartermaster Hudson - 15127, -- Samuel Hawke - 10380, -- Sanuye Runetotem - 12785, -- Sergeant Major Clate - 5821, -- Sheldon Von Croy - 18926, -- Sleyin - 3356, -- Sumi - 3022, -- Sunn Ragetotem - 19436, -- Supply Master Broog - 2999, -- Taur Stonehoof - 1350, -- Theresa Moulaine - 984, -- Thralosh - 27188, -- Tonraq - 10369, -- Trayexir - 16762, -- Treall - 3079, -- Varg Windwhisper - 896, -- Veldan Lightfoot - 1146, -- Vharr - 26599, -- Willis Wobblewheel - 1309, -- Wynne Larson - 11137, -- Xai'ander - 20082, -- Yarley - 4884, -- Zulrg - 24347, -- Alexis Walker - 1315, -- Allan Hafgan - 10379, -- Altsoba Ragetotem - 4172, -- Anadyia - 2046, -- Andrew Krighton - 25196, -- Archer Delvinar - 28855, -- Ba'kari - 2116, -- Blacksmith Rand - 11183, -- Blixxrak - 21112, -- Bossi Pentapiston - 1441, -- Brak Durnad - 5123, -- Bretta Goldfury - 31024, -- Brock Thriss - 33599, -- Brollen Wheatbeard - 1319, -- Bryan Cross - 6028, -- Burkrum - 26393, -- Captain Dirgehammer - 26394, -- Captain O'Neal - 1291, -- Carla Granger - 19056, -- Cecil Meyers - 4569, -- Charles Seaton - 3166, -- Cutac - 956, -- Dorin Songblade - 10293, -- Dulciea Frostmoon - 6300, -- Elisa Steelhand - 3020, -- Etu Ragetotem - 1310, -- Evan Larson - 18997, -- Fallesh Sunfallow - 1296, -- Felder Stover - 225, -- Gavin Gnarltree - 1333, -- Gerik Koen - 3165, -- Ghrawt - 4232, -- Glorandiir - 1213, -- Godric Rothgar - 4556, -- Gordon Wendham - 16716, -- Gornii - 11703, -- Graw Cornerstone - 1273, -- Grawn Thromwyn - 980, -- Grimnal - 3093, -- Grod - 12045, -- Hae'Wilani - 28797, -- Haley Copperturn - 30436, -- Halig Fireforge - 5119, -- Hegnar Swiftaxe - 1324, -- Heinrich Stone - 1147, -- Hragran - 37991, -- Ikfirus the Vile - 78, -- Janos Hammerknuckle - 38840, -- Jedebia - 3610, -- Jeena Featherbow - 1454, -- Jennabink Powerseam - 16625, -- Keeli - 22491, -- Kerpow Blastwrench - 4231, -- Kieran - 29253, -- Koloth - 1381, -- Krakk - 4173, -- Landria - 1295, -- Lara Moore - 31027, -- Leeka Turner - 5129, -- Lissyphus Finespindle - 3658, -- Lizzarik - 4557, -- Louis Warren - 4580, -- Lucille Castleton - 226, -- Morg Gnarltree - 3321, -- Morgum - 17930, -- Nabek - 1459, -- Naela Trance - 31805, -- Nagojut - 3317, -- Ollanus - 5126, -- Olthran Craghelm - 29969, -- Ontak - 19370, -- Ordinn Thunderfist - 24330, -- Orson Locke - 18278, -- Pilot Marsha - 3684, -- Pizznukle - 16678, -- Rahein - 1198, -- Rallic Finn - 1695, -- Rendow - 945, -- Rybrad Coldbank - 23724, -- Samir - 28871, -- Scabbard - 27055, -- Sentinel Amberline - 4185, -- Shaldyn - 3609, -- Shalomon - 1407, -- Sranda - 5508, -- Strumner Flintheel - 3023, -- Sura Wildmane - 3053, -- Synge - 24028, -- Talu Frosthoof - 5510, -- Thulman Flintcrag - 4259, -- Thurgrum Deepforge - 4559, -- Timothy Weldon - 3315, -- Tor'phan - 5812, -- Tumi - 3488, -- Uthrok - 16186, -- Vara - 4175, -- Vinasia - 29497, -- Walther Whiteford - 1341, -- Wilhelm Strang - 20112, -- Wind Trader Tuluman - 16693, -- Winthren - 8129, -- Wrinkle Goodsteel - 16750, -- Yil - 9552, -- Zanara - 23897, -- Zungam - 16623, -- Zyandrel - 3952, -- Aeolynn - 8359, -- Ahanu - 28800, -- Aidan Steeleye - 3552, -- Alexandre Lefevre - 3554, -- Andrea Boynton - 4234, -- Andrus - 2113, -- Archibald Kava - 16260, -- Areyn - 4203, -- Ariyell Skyshadow - 18962, -- Bar Talet - 3097, -- Bernard Brubaker - 5152, -- Bingus - 17245, -- Blacksmith Calypso - 9549, -- Borand - 5120, -- Brenwyn Wintersteel - 27062, -- Brom Armstrong - 5106, -- Bromiir Ormsen - 3075, -- Bronk Steelrage - 19499, -- Cahill - 3522, -- Constance Brisboise - 54, -- Corina Steele - 29476, -- Dagna Flintlock - 19530, -- Darmend - 3019, -- Delgo Ragetotem - 5125, -- Dolkin Craghelm - 5102, -- Dolman Steelfury - 1462, -- Edwina Monzor - 24052, -- Eldrim Mounder - 2137, -- Eliza Callen - 16670, -- Eriden - 26934, -- Everett McGill - 2845, -- Fargon Mortalak - 3095, -- Fela - 30253, -- Felindel Sunhammer - 23862, -- Finlay Fletcher - 4601, -- Francis Eliot - 4600, -- Geoffrey Hartwell - 16257, -- Geron - 3000, -- Gibbert - 16753, -- Gotaan - 3493, -- Grazlix - 5103, -- Grenil Steelfury - 23144, -- Gug - 19561, -- Hagash the Blind - 3486, -- Halija Whitestrider - 3316, -- Handor - 4886, -- Hans Weston - 2839, -- Haren Kanmae - 4187, -- Harlon Thornguard - 2117, -- Harold Raims - 1243, -- Hegnar Rumbleshot - 3088, -- Henry Chapal - 8358, -- Hewa - 3018, -- Hogor Thunderhoof - 3477, -- Hraq - 4188, -- Illyanie - 3483, -- Jahan Hawkwing - 3590, -- Janna Brightmoon - 1471, -- Jannos Ironwill - 23908, -- Jhet Ironbeard - 2997, -- Jyn Stonehoof - 3331, -- Kareth - 5816, -- Katis - 3078, -- Kennah Hawkseye - 29496, -- Kerta the Bold - 3683, -- Kiknikle - 789, -- Kimberly Hiett - 17929, -- Kioni - 3359, -- Kiro - 2840, -- Kizz Bluntstrike - 16388, -- Koren - 19339, -- Korthul - 4883, -- Krak - 27185, -- Kuk'uq - 32253, -- Kyunghee - 3159, -- Kzan Thornslash - 26707, -- Litoko Icetotem - 19694, -- Loolruna - 19239, -- Mahir Redstroke - 3077, -- Mahnott Roughwound - 16747, -- Mahri - 5107, -- Mangorn Flinthammer - 1287, -- Marda Weller - 4888, -- Marie Holdston - 3073, -- Marjak Keenblade - 16620, -- Mathaleron - 1322, -- Maxton Strang - 1339, -- Mayda Thane - 12024, -- Meliri - 5819, -- Mirelle Tremayne - 9555, -- Mu'uta - 3330, -- Muragus - 1461, -- Murndan Derth - 15315, -- Mylini Frostmoon - 4233, -- Mythidan - 4183, -- Naram Longclaw - 3479, -- Nargal Deatheye - 12029, -- Narianna - 4592, -- Nathaniel Steenwick - 11182, -- Nixxrak - 2136, -- Oliver Dwor - 19479, -- Orgatha - 16632, -- Oss - 16263, -- Paelarin - 4890, -- Piter Verance - 3530, -- Pyrewood Tailor - 31804, -- Qatiichii - 19452, -- Quartermaster Drake - 19236, -- Quelama Lightblade - 19473, -- Raiza - 3161, -- Rarc - 23571, -- Razbo Rustgear - 22225, -- Reagan Mancuso - 21086, -- Ruka - 4597, -- Samuel Van Brunt - 3553, -- Sebastian Meloche - 1320, -- Seoman Griffith - 14371, -- Shen'dralar Provisioner - 20890, -- Siflaed Coldhammer - 3612, -- Sinda - 5122, -- Skolmin Goldfury - 19012, -- Sparik - 4570, -- Sydney Upton - 3092, -- Tagain - 3953, -- Tandaan Lightmane - 27711, -- Technician Halmaha - 7976, -- Thalgus Thunderfist - 26901, -- Torik - 4889, -- Torq Ironblast - 4235, -- Turian - 3177, -- Turuk Amberstill - 16626, -- Tynna - 3163, -- Uhgar - 3074, -- Varia Hardhide - 16714, -- Ven - 3492, -- Vexspindle - 1469, -- Vrok Blunderblast - 4560, -- Walter Ellingson - 11184, -- Wixxrak - 8159, -- Worb Strongstitch - 5754, -- Zane Bradford - 16636, -- Zathanna + [MINIMAP_TRACKING_REPAIR] = { + [19373] = true, -- Mari Stonehand + [28995] = true, -- Paldesse + [16583] = true, -- Rohok + [34252] = true, -- Dubin Clay + [28992] = true, -- Valerie Langrom + [37687] = true, -- Alchemist Finklestein + [29523] = true, -- Bragund Brightlink + [28997] = true, -- Griselda Hunderland + [25206] = true, -- Ahlurglgr + [31863] = true, -- Nargle Lashcord + [35496] = true, -- Rueben Lauren + [35498] = true, -- Horace Hunderland + [23381] = true, -- Tydormu + [38316] = true, -- Ormus the Penitent + [17904] = true, -- Fedryen Swiftspear + [28040] = true, -- Mardan Thunderhoof + [3392] = true, -- Prospector Khazgorm + [35497] = true, -- Rafael Langrom + [14624] = true, -- Master Smith Burninate + [18011] = true, -- Zurai + [35500] = true, -- Matilda Brightlink + [38858] = true, -- Goodman the "Closer" + [8161] = true, -- Harggan + [19662] = true, -- Aaron Hollman + [19575] = true, -- Qiff + [34087] = true, -- Trapjaw Rix + [38283] = true, -- Malfus Grimfrost + [18382] = true, -- Mycah + [31864] = true, -- Xazi Smolderpipe + [14754] = true, -- Kelm Hargunth + [12788] = true, -- Legionnaire Teena + [14921] = true, -- Rin'wosho the Trader + [19383] = true, -- Captured Gnome + [33594] = true, -- Fizzix Blastbolt + [12778] = true, -- Lieutenant Rachel Vaccar + [32385] = true, -- Doris Volanthius + [30006] = true, -- Warsmith Sigfinna + [19536] = true, -- Dealer Jadyan + [28722] = true, -- Bryan Landers + [37696] = true, -- Crusader Halford + [3322] = true, -- Kaja + [7852] = true, -- Pratt McGrubben + [29494] = true, -- Shen Kang Cheng + [29014] = true, -- Grakjek + [14753] = true, -- Illiyana Moonblaze + [28990] = true, -- Anthony Durain + [32381] = true, -- Captain Dirgehammer + [8176] = true, -- Gharash + [27037] = true, -- Hidetrader Jun'ik + [16631] = true, -- Andra + [31781] = true, -- Blast Thunderbomb + [11278] = true, -- Magnus Frostwake + [37998] = true, -- Talan Moonstrike + [32834] = true, -- Knight-Lieutenant Moonstrike + [28500] = true, -- Master Siegesmith Corvus + [37992] = true, -- Tortunok + [32832] = true, -- Blood Guard Zar'shi + [16376] = true, -- Craftsman Wilhelm + [1669] = true, -- Defias Profiteer + [3682] = true, -- Vrang Wildgore + [1298] = true, -- Frederick Stover + [15289] = true, -- Raelis Dawnstar + [31865] = true, -- Zom Bocom + [10857] = true, -- Argent Quartermaster Lightspark + [12782] = true, -- Captain O'Neal + [31776] = true, -- Frazzle Geargrinder + [9179] = true, -- Jazzrik + [20242] = true, -- Karaaz + [15126] = true, -- Rutherford Twing + [27011] = true, -- Broff Bombast + [29688] = true, -- Engineer Reed + [25314] = true, -- Archmage Berinand + [37688] = true, -- Crusader Grimtong + [15909] = true, -- Fariel Starsong + [26081] = true, -- High Admiral "Shelly" Jorrik + [3319] = true, -- Sana + [15176] = true, -- Vargus + [37999] = true, -- Alana Moonstrike + [15292] = true, -- Faraden Thelryn + [37993] = true, -- Gerardo the Suave + [5170] = true, -- Hjoldir Stoneblade + [3589] = true, -- Keina + [21183] = true, -- Oronok Torn-heart + [14581] = true, -- Sergeant Thunderhorn + [3534] = true, -- Wallace the Blind + [3167] = true, -- Wuark + [32594] = true, -- Calder + [38181] = true, -- Haragg the Unseen + [19342] = true, -- Krek Cragcrush + [19011] = true, -- Osrok the Immovable + [23007] = true, -- Paulsta'ats + [38054] = true, -- Scott the Merciful + [25046] = true, -- Smith Hauthaa + [13217] = true, -- Thanthaldis Snowgleam + [3314] = true, -- Urtharo + [38284] = true, -- Uvlus Banefire + [28991] = true, -- Valaden Silverblade + [29907] = true, -- Xark Bolthammer + [3537] = true, -- Zixil + [2135] = true, -- Abe Winters + [228] = true, -- Avette Fellwood + [3951] = true, -- Bhaldaran Ravenshade + [28344] = true, -- Blazzle + [1687] = true, -- Cliff Hadin + [19526] = true, -- Dunaman + [30434] = true, -- Durik Bronzebomb + [23367] = true, -- Grella + [16823] = true, -- Humphry + [2844] = true, -- Hurklor + [2843] = true, -- Jutak + [5411] = true, -- Krinkle Goodsteel + [12942] = true, -- Leonard Porter + [3529] = true, -- Moonrage Armorer + [1645] = true, -- Quartermaster Hicks + [32383] = true, -- Sergeant Thunderhorn + [20231] = true, -- Supply Officer Pestle + [28989] = true, -- Aemara + [8131] = true, -- Blizrik Buckshot + [1450] = true, -- Brahnmar + [21474] = true, -- Coreiel + [4164] = true, -- Cylania + [27943] = true, -- Dalormi + [1686] = true, -- Irene Sureshot + [29252] = true, -- Jason Riggins + [16918] = true, -- Jel + [19047] = true, -- Lissaf + [29945] = true, -- Marksman Udabu + [3539] = true, -- Ott + [28716] = true, -- Palja Amboss + [24188] = true, -- Samuel Rosemond + [14737] = true, -- Smith Slagtree + [1690] = true, -- Thrawn Boltar + [3349] = true, -- Ukra'nor + [16637] = true, -- Welethelon + [2679] = true, -- Wenna Silkbeard + [19517] = true, -- Alorra + [20613] = true, -- Arodis Sunblade + [16715] = true, -- Avelii + [17667] = true, -- Beega + [4602] = true, -- Benijah Fenner + [14301] = true, -- Brinna Valanaar + [26600] = true, -- Chief Engineer Galpen Rolltie + [1314] = true, -- Duncan Cullen + [13216] = true, -- Gaelden Hammersmith + [3343] = true, -- Grelkor + [13218] = true, -- Grunnda Wolfheart + [30067] = true, -- Initiate Claget + [13219] = true, -- Jekyll Flandring + [3015] = true, -- Kuna Thunderhorn + [74] = true, -- Kurran Steele + [19520] = true, -- Lelagar + [4177] = true, -- Melea + [38182] = true, -- Niby the Almighty + [16528] = true, -- Provisioner Vredigar + [5108] = true, -- Raena Flinthammer + [19240] = true, -- Selanam the Blade + [18672] = true, -- Thomas Yance + [19238] = true, -- Urumir Stavebright + [38841] = true, -- Vol'guk + [22099] = true, -- Wyrmcult Provisioner + [2482] = true, -- Zarena Cromwind + [3409] = true, -- Zendo'jian + [20917] = true, -- Zinyen Swiftstrider + [1214] = true, -- Aldren Cordon + [3592] = true, -- Andiss + [27667] = true, -- Anwehu + [1312] = true, -- Ardwyn Cailen + [10856] = true, -- Argent Quartermaster Hasana + [28796] = true, -- Arlen Brighthammer + [29499] = true, -- Bartram Haller + [1240] = true, -- Boran Ironclink + [12777] = true, -- Captain Dirgehammer + [29964] = true, -- Dargum Hammerdeep + [14337] = true, -- Field Repair Bot [74] = trueA + [3080] = true, -- Harant Ironbrace + [28760] = true, -- Hargus the Geist + [29538] = true, -- Hexil Garrot + [3160] = true, -- Huklah + [5155] = true, -- Ingrys Stonebrow + [15291] = true, -- Jainthess Thelryn + [12023] = true, -- Kharedon + [12792] = true, -- Lady Palanseer + [4558] = true, -- Lauren Newcomb + [27139] = true, -- Librarian Whitley + [4186] = true, -- Mavralyn + [3533] = true, -- Moonrage Leatherworker + [167] = true, -- Morhan Coppertongue + [8878] = true, -- Muuran + [4085] = true, -- Nizzik + [16691] = true, -- Noraelath + [22264] = true, -- Ogri'la Steelshaper + [17412] = true, -- Phaedra + [3528] = true, -- Pyrewood Armorer + [3532] = true, -- Pyrewood Leatherworker + [2849] = true, -- Qixdi Goodstitch + [3543] = true, -- Robert Aebischer + [27134] = true, -- Smith Prigka + [9551] = true, -- Starn + [18426] = true, -- Terellia + [1668] = true, -- William MacGregor + [37997] = true, -- Yili + [9544] = true, -- Yuka Screwspigot + [21485] = true, -- Aldraan + [25274] = true, -- Armorer Orkuruk + [20616] = true, -- Asuur + [22476] = true, -- Aundro + [16917] = true, -- Aurok + [23735] = true, -- Bartleby Armorfist + [3611] = true, -- Brannol Eaglemoon + [4240] = true, -- Caynrus + [16619] = true, -- Celana + [27151] = true, -- Deniigi + [190] = true, -- Dermot Johns + [836] = true, -- Durnan Furcutter + [4180] = true, -- Ealyshia Dewwhisper + [28813] = true, -- Elizabeth Hollingsworth + [28943] = true, -- Fineous + [1698] = true, -- Frast Dokner + [3591] = true, -- Freja Nightwing + [4184] = true, -- Geenia Sunshadow + [19333] = true, -- Grokom Deatheye + [1289] = true, -- Gunther Weller + [19879] = true, -- Horvon the Armorer + [3491] = true, -- Ironzar + [2847] = true, -- Jansen Underwood + [3410] = true, -- Jin'sora + [5512] = true, -- Kaita Deepforge + [3021] = true, -- Kard Ragetotem + [954] = true, -- Kat Sampson + [4257] = true, -- Lana Thunderbrew + [29035] = true, -- Loomee + [18010] = true, -- Maktu + [22227] = true, -- Markus Scylan + [27045] = true, -- Master Smith Devin Brevig + [4171] = true, -- Merelyssa + [3613] = true, -- Meri Ironweave + [3531] = true, -- Moonrage Tailor + [16919] = true, -- Mura + [9553] = true, -- Nadia Vernon + [16274] = true, -- Narina + [4603] = true, -- Nicholas Atwood + [12805] = true, -- Officer Areyn + [27267] = true, -- Quartermaster Bartlett + [30336] = true, -- Runesmith Balehammer + [16261] = true, -- Sathiel + [12799] = true, -- Sergeant Ba'sha + [37903] = true, -- Shely Steelbowels + [3361] = true, -- Shoma + [27019] = true, -- Siegesmith Gulda + [19315] = true, -- Supply Officer Isabel + [19314] = true, -- Supply Officer Shandria + [19001] = true, -- Talaara + [26697] = true, -- Tewah Chillmane + [26229] = true, -- Tiernan Anvilheart + [26898] = true, -- Troz + [4086] = true, -- Veenix + [4604] = true, -- Abigail Sawyer + [1349] = true, -- Agustus Moulaine + [19043] = true, -- Ahemen + [1294] = true, -- Aldric Moore + [20463] = true, -- Apprentice Andrethan + [15400] = true, -- Arathel Sunforge + [17655] = true, -- Blacksmith Frances + [3162] = true, -- Burdrak Harglhelm + [9548] = true, -- Cawind Trueaim + [32477] = true, -- Chester Copperpot + [4236] = true, -- Cyridan + [19351] = true, -- Daggle Ironshaper + [29923] = true, -- Dagni Oregleam + [27067] = true, -- Drigoth + [8360] = true, -- Elki + [16765] = true, -- Ellomin + [16258] = true, -- Farsil + [16666] = true, -- Feledis + [4043] = true, -- Galthuk + [1238] = true, -- Gamili Frosthide + [5820] = true, -- Gillian Moore + [1362] = true, -- Gothor Brumn + [1348] = true, -- Gregory Ardus + [1104] = true, -- Grundel Harkin + [10361] = true, -- Gruul Darkblade + [5133] = true, -- Harick Boulderdrum + [981] = true, -- Hartash + [2483] = true, -- Jaquilina Dramet + [4892] = true, -- Jensen Farran + [793] = true, -- Kara Adams + [5509] = true, -- Kathrum Axehand + [5121] = true, -- Kelomir Ironhand + [3588] = true, -- Khardan Proudblade + [3360] = true, -- Koru + [3536] = true, -- Kris Legace + [30241] = true, -- Lanudal Silverhart + [12784] = true, -- Lieutenant Jackspring + [1297] = true, -- Lina Stover + [1299] = true, -- Lisbeth Schneider + [5156] = true, -- Maeva Snowbraid + [37936] = true, -- Morgan Dayblaze + [959] = true, -- Morley Eberlein + [16735] = true, -- Muhaa + [222] = true, -- Nillen Andemar + [30572] = true, -- Nofal + [8398] = true, -- Ohanko + [23159] = true, -- Okuno + [1323] = true, -- Osric Strang + [1249] = true, -- Quartermaster Hudson + [15127] = true, -- Samuel Hawke + [10380] = true, -- Sanuye Runetotem + [12785] = true, -- Sergeant Major Clate + [5821] = true, -- Sheldon Von Croy + [18926] = true, -- Sleyin + [3356] = true, -- Sumi + [3022] = true, -- Sunn Ragetotem + [19436] = true, -- Supply Master Broog + [2999] = true, -- Taur Stonehoof + [1350] = true, -- Theresa Moulaine + [984] = true, -- Thralosh + [27188] = true, -- Tonraq + [10369] = true, -- Trayexir + [16762] = true, -- Treall + [3079] = true, -- Varg Windwhisper + [896] = true, -- Veldan Lightfoot + [1146] = true, -- Vharr + [26599] = true, -- Willis Wobblewheel + [1309] = true, -- Wynne Larson + [11137] = true, -- Xai'ander + [20082] = true, -- Yarley + [4884] = true, -- Zulrg + [24347] = true, -- Alexis Walker + [1315] = true, -- Allan Hafgan + [10379] = true, -- Altsoba Ragetotem + [4172] = true, -- Anadyia + [2046] = true, -- Andrew Krighton + [25196] = true, -- Archer Delvinar + [28855] = true, -- Ba'kari + [2116] = true, -- Blacksmith Rand + [11183] = true, -- Blixxrak + [21112] = true, -- Bossi Pentapiston + [1441] = true, -- Brak Durnad + [5123] = true, -- Bretta Goldfury + [31024] = true, -- Brock Thriss + [33599] = true, -- Brollen Wheatbeard + [1319] = true, -- Bryan Cross + [6028] = true, -- Burkrum + [26393] = true, -- Captain Dirgehammer + [26394] = true, -- Captain O'Neal + [1291] = true, -- Carla Granger + [19056] = true, -- Cecil Meyers + [4569] = true, -- Charles Seaton + [3166] = true, -- Cutac + [956] = true, -- Dorin Songblade + [10293] = true, -- Dulciea Frostmoon + [6300] = true, -- Elisa Steelhand + [3020] = true, -- Etu Ragetotem + [1310] = true, -- Evan Larson + [18997] = true, -- Fallesh Sunfallow + [1296] = true, -- Felder Stover + [225] = true, -- Gavin Gnarltree + [1333] = true, -- Gerik Koen + [3165] = true, -- Ghrawt + [4232] = true, -- Glorandiir + [1213] = true, -- Godric Rothgar + [4556] = true, -- Gordon Wendham + [16716] = true, -- Gornii + [11703] = true, -- Graw Cornerstone + [1273] = true, -- Grawn Thromwyn + [980] = true, -- Grimnal + [3093] = true, -- Grod + [12045] = true, -- Hae'Wilani + [28797] = true, -- Haley Copperturn + [30436] = true, -- Halig Fireforge + [5119] = true, -- Hegnar Swiftaxe + [1324] = true, -- Heinrich Stone + [1147] = true, -- Hragran + [37991] = true, -- Ikfirus the Vile + [78] = true, -- Janos Hammerknuckle + [38840] = true, -- Jedebia + [3610] = true, -- Jeena Featherbow + [1454] = true, -- Jennabink Powerseam + [16625] = true, -- Keeli + [22491] = true, -- Kerpow Blastwrench + [4231] = true, -- Kieran + [29253] = true, -- Koloth + [1381] = true, -- Krakk + [4173] = true, -- Landria + [1295] = true, -- Lara Moore + [31027] = true, -- Leeka Turner + [5129] = true, -- Lissyphus Finespindle + [3658] = true, -- Lizzarik + [4557] = true, -- Louis Warren + [4580] = true, -- Lucille Castleton + [226] = true, -- Morg Gnarltree + [3321] = true, -- Morgum + [17930] = true, -- Nabek + [1459] = true, -- Naela Trance + [31805] = true, -- Nagojut + [3317] = true, -- Ollanus + [5126] = true, -- Olthran Craghelm + [29969] = true, -- Ontak + [19370] = true, -- Ordinn Thunderfist + [24330] = true, -- Orson Locke + [18278] = true, -- Pilot Marsha + [3684] = true, -- Pizznukle + [16678] = true, -- Rahein + [1198] = true, -- Rallic Finn + [1695] = true, -- Rendow + [945] = true, -- Rybrad Coldbank + [23724] = true, -- Samir + [28871] = true, -- Scabbard + [27055] = true, -- Sentinel Amberline + [4185] = true, -- Shaldyn + [3609] = true, -- Shalomon + [1407] = true, -- Sranda + [5508] = true, -- Strumner Flintheel + [3023] = true, -- Sura Wildmane + [3053] = true, -- Synge + [24028] = true, -- Talu Frosthoof + [5510] = true, -- Thulman Flintcrag + [4259] = true, -- Thurgrum Deepforge + [4559] = true, -- Timothy Weldon + [3315] = true, -- Tor'phan + [5812] = true, -- Tumi + [3488] = true, -- Uthrok + [16186] = true, -- Vara + [4175] = true, -- Vinasia + [29497] = true, -- Walther Whiteford + [1341] = true, -- Wilhelm Strang + [20112] = true, -- Wind Trader Tuluman + [16693] = true, -- Winthren + [8129] = true, -- Wrinkle Goodsteel + [16750] = true, -- Yil + [9552] = true, -- Zanara + [23897] = true, -- Zungam + [16623] = true, -- Zyandrel + [3952] = true, -- Aeolynn + [8359] = true, -- Ahanu + [28800] = true, -- Aidan Steeleye + [3552] = true, -- Alexandre Lefevre + [3554] = true, -- Andrea Boynton + [4234] = true, -- Andrus + [2113] = true, -- Archibald Kava + [16260] = true, -- Areyn + [4203] = true, -- Ariyell Skyshadow + [18962] = true, -- Bar Talet + [3097] = true, -- Bernard Brubaker + [5152] = true, -- Bingus + [17245] = true, -- Blacksmith Calypso + [9549] = true, -- Borand + [5120] = true, -- Brenwyn Wintersteel + [27062] = true, -- Brom Armstrong + [5106] = true, -- Bromiir Ormsen + [3075] = true, -- Bronk Steelrage + [19499] = true, -- Cahill + [3522] = true, -- Constance Brisboise + [54] = true, -- Corina Steele + [29476] = true, -- Dagna Flintlock + [19530] = true, -- Darmend + [3019] = true, -- Delgo Ragetotem + [5125] = true, -- Dolkin Craghelm + [5102] = true, -- Dolman Steelfury + [1462] = true, -- Edwina Monzor + [24052] = true, -- Eldrim Mounder + [2137] = true, -- Eliza Callen + [16670] = true, -- Eriden + [26934] = true, -- Everett McGill + [2845] = true, -- Fargon Mortalak + [3095] = true, -- Fela + [30253] = true, -- Felindel Sunhammer + [23862] = true, -- Finlay Fletcher + [4601] = true, -- Francis Eliot + [4600] = true, -- Geoffrey Hartwell + [16257] = true, -- Geron + [3000] = true, -- Gibbert + [16753] = true, -- Gotaan + [3493] = true, -- Grazlix + [5103] = true, -- Grenil Steelfury + [23144] = true, -- Gug + [19561] = true, -- Hagash the Blind + [3486] = true, -- Halija Whitestrider + [3316] = true, -- Handor + [4886] = true, -- Hans Weston + [2839] = true, -- Haren Kanmae + [4187] = true, -- Harlon Thornguard + [2117] = true, -- Harold Raims + [1243] = true, -- Hegnar Rumbleshot + [3088] = true, -- Henry Chapal + [8358] = true, -- Hewa + [3018] = true, -- Hogor Thunderhoof + [3477] = true, -- Hraq + [4188] = true, -- Illyanie + [3483] = true, -- Jahan Hawkwing + [3590] = true, -- Janna Brightmoon + [1471] = true, -- Jannos Ironwill + [23908] = true, -- Jhet Ironbeard + [2997] = true, -- Jyn Stonehoof + [3331] = true, -- Kareth + [5816] = true, -- Katis + [3078] = true, -- Kennah Hawkseye + [29496] = true, -- Kerta the Bold + [3683] = true, -- Kiknikle + [789] = true, -- Kimberly Hiett + [17929] = true, -- Kioni + [3359] = true, -- Kiro + [2840] = true, -- Kizz Bluntstrike + [16388] = true, -- Koren + [19339] = true, -- Korthul + [4883] = true, -- Krak + [27185] = true, -- Kuk'uq + [32253] = true, -- Kyunghee + [3159] = true, -- Kzan Thornslash + [26707] = true, -- Litoko Icetotem + [19694] = true, -- Loolruna + [19239] = true, -- Mahir Redstroke + [3077] = true, -- Mahnott Roughwound + [16747] = true, -- Mahri + [5107] = true, -- Mangorn Flinthammer + [1287] = true, -- Marda Weller + [4888] = true, -- Marie Holdston + [3073] = true, -- Marjak Keenblade + [16620] = true, -- Mathaleron + [1322] = true, -- Maxton Strang + [1339] = true, -- Mayda Thane + [12024] = true, -- Meliri + [5819] = true, -- Mirelle Tremayne + [9555] = true, -- Mu'uta + [3330] = true, -- Muragus + [1461] = true, -- Murndan Derth + [15315] = true, -- Mylini Frostmoon + [4233] = true, -- Mythidan + [4183] = true, -- Naram Longclaw + [3479] = true, -- Nargal Deatheye + [12029] = true, -- Narianna + [4592] = true, -- Nathaniel Steenwick + [11182] = true, -- Nixxrak + [2136] = true, -- Oliver Dwor + [19479] = true, -- Orgatha + [16632] = true, -- Oss + [16263] = true, -- Paelarin + [4890] = true, -- Piter Verance + [3530] = true, -- Pyrewood Tailor + [31804] = true, -- Qatiichii + [19452] = true, -- Quartermaster Drake + [19236] = true, -- Quelama Lightblade + [19473] = true, -- Raiza + [3161] = true, -- Rarc + [23571] = true, -- Razbo Rustgear + [22225] = true, -- Reagan Mancuso + [21086] = true, -- Ruka + [4597] = true, -- Samuel Van Brunt + [3553] = true, -- Sebastian Meloche + [1320] = true, -- Seoman Griffith + [14371] = true, -- Shen'dralar Provisioner + [20890] = true, -- Siflaed Coldhammer + [3612] = true, -- Sinda + [5122] = true, -- Skolmin Goldfury + [19012] = true, -- Sparik + [4570] = true, -- Sydney Upton + [3092] = true, -- Tagain + [3953] = true, -- Tandaan Lightmane + [27711] = true, -- Technician Halmaha + [7976] = true, -- Thalgus Thunderfist + [26901] = true, -- Torik + [4889] = true, -- Torq Ironblast + [4235] = true, -- Turian + [3177] = true, -- Turuk Amberstill + [16626] = true, -- Tynna + [3163] = true, -- Uhgar + [3074] = true, -- Varia Hardhide + [16714] = true, -- Ven + [3492] = true, -- Vexspindle + [1469] = true, -- Vrok Blunderblast + [4560] = true, -- Walter Ellingson + [11184] = true, -- Wixxrak + [8159] = true, -- Worb Strongstitch + [5754] = true, -- Zane Bradford + [16636] = true, -- Zathanna }, - ["StableMaster"] = { - 26044, -- Durkot Wolfbrother - 28690, -- Tassia Whisperglen - 28047, -- Hadrius Harlowe - 21517, -- Ilthuril - 11069, -- Jenova Stoneshield - 26504, -- Soar Hawkfury - 23392, -- Skyguard Stable Master - 16185, -- Anathos - 16824, -- Master Sergeant Lorin Thalmerok - 26944, -- Soulok Stormfury - 10059, -- Antarius - 11119, -- Azzleby - 10052, -- Maluressian - 15722, -- Squire Leoren Mal'derath - 27010, -- Celidh Aletracker - 30008, -- Kari the Beastmaster - 19019, -- Luftasia - 25037, -- Seraphina Bloodheart - 10056, -- Alassin - 16094, -- Durik - 22469, -- Fiskal Shadowsong - 29906, -- Heksi - 10085, -- Jaelysia - 10050, -- Seikwa - 16656, -- Shalenn - 9980, -- Shelby Stoneflint - 11104, -- Shelgrayn - 35290, -- Steen Horngrass - 13617, -- Stormpike Stable Master - 9984, -- Ulbrek Firehand - 19018, -- Wilda Bearmane - 29959, -- Andurg Slatechest - 10053, -- Anya Maulray - 29740, -- Craga Ironsting - 28790, -- Fala Softhoof - 13616, -- Frostwolf Stable Master - 21336, -- Gedrah - 26721, -- Halona Stormwhisper - 9985, -- Laziphus - 9989, -- Lina Hearthstove - 10047, -- Michael - 9986, -- Shyrka Wolfrunner - 26597, -- Toby "Mother Goose" Ironbolt - 9978, -- Wesley - 10046, -- Bethaine Flinthammer - 10054, -- Bulrug - 29658, -- Chelsea Reese - 10058, -- Greth - 10060, -- Grimestack - 10049, -- Hekkru - 23733, -- Horatio the Stable Boy - 16586, -- Huntsman Torf Angerhoof - 24905, -- Leassian - 16665, -- Paniar - 9982, -- Penny - 15131, -- Qeeju - 10063, -- Reggifuz - 9977, -- Sylista - 18984, -- Trag - 11105, -- Aboda - 16764, -- Arthaid - 17666, -- Astur - 11117, -- Awenasa - 19368, -- Crinn Pathfinder - 6749, -- Erma - 17485, -- Esbina - 10048, -- Gereck - 14741, -- Huntsman Markhor - 18250, -- Joraal - 17896, -- Kameel Longstride - 9983, -- Kelsuwa - 18244, -- Khalan - 10061, -- Killium Bouldertoe - 10045, -- Kirk Maxwell - 24974, -- Liza Cutlerflix - 19476, -- Lor - 10055, -- Morganus - 22468, -- Ogrin - 21518, -- Oruhe - 24350, -- Robert Clarke - 9979, -- Sarah Goode - 10051, -- Seriadne - 9987, -- Shoja'my - 9981, -- Sikwa - 10062, -- Steven Black - 9976, -- Tharlidun - 10057, -- Theodore Mont Claire - 9988, -- Xon'cha + [MINIMAP_TRACKING_STABLEMASTER] = { + [26044] = true, -- Durkot Wolfbrother + [28690] = true, -- Tassia Whisperglen + [28047] = true, -- Hadrius Harlowe + [21517] = true, -- Ilthuril + [11069] = true, -- Jenova Stoneshield + [26504] = true, -- Soar Hawkfury + [23392] = true, -- Skyguard Stable Master + [16185] = true, -- Anathos + [16824] = true, -- Master Sergeant Lorin Thalmerok + [26944] = true, -- Soulok Stormfury + [10059] = true, -- Antarius + [11119] = true, -- Azzleby + [10052] = true, -- Maluressian + [15722] = true, -- Squire Leoren Mal'derath + [27010] = true, -- Celidh Aletracker + [30008] = true, -- Kari the Beastmaster + [19019] = true, -- Luftasia + [25037] = true, -- Seraphina Bloodheart + [10056] = true, -- Alassin + [16094] = true, -- Durik + [22469] = true, -- Fiskal Shadowsong + [29906] = true, -- Heksi + [10085] = true, -- Jaelysia + [10050] = true, -- Seikwa + [16656] = true, -- Shalenn + [9980] = true, -- Shelby Stoneflint + [11104] = true, -- Shelgrayn + [35290] = true, -- Steen Horngrass + [13617] = true, -- Stormpike Stable Master + [9984] = true, -- Ulbrek Firehand + [19018] = true, -- Wilda Bearmane + [29959] = true, -- Andurg Slatechest + [10053] = true, -- Anya Maulray + [29740] = true, -- Craga Ironsting + [28790] = true, -- Fala Softhoof + [13616] = true, -- Frostwolf Stable Master + [21336] = true, -- Gedrah + [26721] = true, -- Halona Stormwhisper + [9985] = true, -- Laziphus + [9989] = true, -- Lina Hearthstove + [10047] = true, -- Michael + [9986] = true, -- Shyrka Wolfrunner + [26597] = true, -- Toby "Mother Goose" Ironbolt + [9978] = true, -- Wesley + [10046] = true, -- Bethaine Flinthammer + [10054] = true, -- Bulrug + [29658] = true, -- Chelsea Reese + [10058] = true, -- Greth + [10060] = true, -- Grimestack + [10049] = true, -- Hekkru + [23733] = true, -- Horatio the Stable Boy + [16586] = true, -- Huntsman Torf Angerhoof + [24905] = true, -- Leassian + [16665] = true, -- Paniar + [9982] = true, -- Penny + [15131] = true, -- Qeeju + [10063] = true, -- Reggifuz + [9977] = true, -- Sylista + [18984] = true, -- Trag + [11105] = true, -- Aboda + [16764] = true, -- Arthaid + [17666] = true, -- Astur + [11117] = true, -- Awenasa + [19368] = true, -- Crinn Pathfinder + [6749] = true, -- Erma + [17485] = true, -- Esbina + [10048] = true, -- Gereck + [14741] = true, -- Huntsman Markhor + [18250] = true, -- Joraal + [17896] = true, -- Kameel Longstride + [9983] = true, -- Kelsuwa + [18244] = true, -- Khalan + [10061] = true, -- Killium Bouldertoe + [10045] = true, -- Kirk Maxwell + [24974] = true, -- Liza Cutlerflix + [19476] = true, -- Lor + [10055] = true, -- Morganus + [22468] = true, -- Ogrin + [21518] = true, -- Oruhe + [24350] = true, -- Robert Clarke + [9979] = true, -- Sarah Goode + [10051] = true, -- Seriadne + [9987] = true, -- Shoja'my + [9981] = true, -- Sikwa + [10062] = true, -- Steven Black + [9976] = true, -- Tharlidun + [10057] = true, -- Theodore Mont Claire + [9988] = true, -- Xon'cha }, - ["Tabard"] = { - 4161, -- Lysheana - 4974, -- Aldwin Laughlin - 5193, -- Rebecca Laughlin - 28774, -- Andrew Matthews - 5130, -- Jondor Steelbrow - 5054, -- Krumn - 5052, -- Edward Remington - 16734, -- Funaam - 16568, -- Tandrine - 3370, -- Urtrun Clanbringer - 4613, -- Christopher Drakul - 5047, -- Ellaercia - 18897, -- "King" Dond - 19861, -- Bip Nigstrom - 19856, -- Steamwheedle Sam + [CHAT_MSG_GUILD] = { + [4161] = true, -- Lysheana + [4974] = true, -- Aldwin Laughlin + [5193] = true, -- Rebecca Laughlin + [28774] = true, -- Andrew Matthews + [5130] = true, -- Jondor Steelbrow + [5054] = true, -- Krumn + [5052] = true, -- Edward Remington + [16734] = true, -- Funaam + [16568] = true, -- Tandrine + [3370] = true, -- Urtrun Clanbringer + [4613] = true, -- Christopher Drakul + [5047] = true, -- Ellaercia + [18897] = true, -- "King" Dond + [19861] = true, -- Bip Nigstrom + [19856] = true, -- Steamwheedle Sam }, - ["Profession"] = { - 29156, -- Archmage Celindra - 28697, -- Timofey Oshenko - 35135, -- Wind Rider Sabamba - 28699, -- Charles Worth - 28746, -- Pilot Vic - 4752, -- Kildar - 35093, -- Wind Rider Jahubo - 26953, -- Thomas Kolichio - 26905, -- Brom Brewbaster - 26986, -- Tiponi Stormwhisper - 28705, -- Katherine Lee - 26989, -- Rollick MacKreel - 28703, -- Linzy Blackbolt - 26972, -- Orn Tenderhoof - 29631, -- Awilo Lon'gomba - 26992, -- Brynna Wilson - 33586, -- Binkie Brightgear - 35100, -- Hargen Bronzewing - 28706, -- Olisarra the Kind - 11073, -- Annora - 8736, -- Buzzek Bracketswing - 35133, -- Maigra Keenfeather - 26964, -- Alexandra McQueen - 26996, -- Awan Iceborn - 27001, -- Darin Goodstitch - 8126, -- Nixx Sprocketspring - 26993, -- Old Man Robert - 4732, -- Randal Hunter - 26997, -- Alestos - 26976, -- Brunna Ironaxe - 28698, -- Jedidiah Handers - 28702, -- Professor Pallin - 25099, -- Jonathan Garrett - 33623, -- Fishing - 5174, -- Springspindle Fizzlegear - 30713, -- Catarina Stanford - 33613, -- Tailoring - 26991, -- Sock Brightbolt - 3494, -- Tinkerwiz - 28694, -- Alard Schmied - 4212, -- Telonis - 25277, -- Chief Engineer Leveny - 33580, -- Dustin Vail - 3064, -- Gennia Runetotem - 33616, -- Herbalism - 26969, -- Raenah - 4772, -- Ultham Ironhorn - 26975, -- Arthur Henslowe - 11868, -- Sayoc - 11052, -- Timothy Worthington - 26999, -- Fendrig Redbeard - 12042, -- Loganaar - 24868, -- Niobe Whizzlespark - 33611, -- Engineering - 2836, -- Brikk Keencraft - 7406, -- Oglethorpe Obnoticus - 27000, -- Trapper Jack - 11097, -- Drakk Stonehand - 19778, -- Farii - 1346, -- Georgio Bolero - 29233, -- Nurse Applewood - 16280, -- Perascamin - 26974, -- Tansy Wildmane - 4773, -- Velma Warnam - 28693, -- Enchanter Nalthanis - 19052, -- Lorokeem - 26998, -- Rosemary Bovard - 23734, -- Anchorite Yazmina - 11869, -- Ansekhwa - 31084, -- Highlord Darion Mograine - 18779, -- Hurnak Grimmord - 30706, -- Jo'mah - 7869, -- Brumn Winterhoof - 33610, -- Enchanting - 5159, -- Daryl Riknussun - 28704, -- Dorothy Egan - 26912, -- Grumbol Stoutpick - 33617, -- Mining - 7944, -- Tinkmaster Overspark - 18777, -- Jelena Nightsky - 2399, -- Daryl Stack - 28696, -- Derik Marks - 26955, -- Jamesina Watterly - 17637, -- Mack Diver - 11017, -- Roxxik - 26914, -- Benjamin Clegg - 30717, -- Elise Brightletter - 30715, -- Feyden Darkin - 26956, -- Sally Tompkins - 26957, -- Angelina Soren - 26909, -- Byron Welwick - 26982, -- Geba'li - 11098, -- Hahrana Ironhide - 28700, -- Diane Cannings - 26961, -- Gunter Hansen - 7948, -- Kylanna Windwhisper - 6287, -- Radnaal Maneweaver - 5482, -- Stephen Ryback - 7954, -- Binjy Featherwhistle - 19775, -- Kalinda - 4258, -- Bengus Deepforge - 19252, -- High Enchanter Bardolan - 26915, -- Ounhulo - 26963, -- Roberta Jacks - 26990, -- Alexis Marlowe - 5885, -- Deino - 33583, -- Fael Morningsong - 26987, -- Falorn Nightwhisper - 5513, -- Gelman Stonehand - 5497, -- Jennea Cannon - 18755, -- Moorutu - 11870, -- Archibald - 26988, -- Argo Strongstout - 26981, -- Crog Steelspine - 33588, -- Crystal Brightspark - 20791, -- Iorioa - 29195, -- Lady Alistra - 34713, -- Ondani Greatmill - 26904, -- Rosina Rivet - 5938, -- Uthan Stillwater - 29194, -- Amal'thazad - 11074, -- Hgarth - 28958, -- Jessa Weaver - 11072, -- Kitta Firewind - 33612, -- Leatherworking - 3355, -- Saru Steelfury - 5504, -- Sheldras Moontree - 26951, -- Wilhelmina Renel - 3399, -- Zamja - 3026, -- Aska Mistrunner - 1232, -- Azar Stronghammer - 4218, -- Denatharion - 32474, -- Fishy Ser'ji - 2837, -- Jaxin Chong - 30721, -- Michael Schwan - 20500, -- Olrokk - 27703, -- Ysuria - 30710, -- Zantasia - 33603, -- Arthur Denny - 4588, -- Arthur Moore - 33609, -- Blacksmithing - 3347, -- Yelmak - 3326, -- Zevrost - 33608, -- Alchemy - 29513, -- Didi the Wrench - 16621, -- Ileda - 20511, -- Ilsa Blusterbrew - 33614, -- Jewelcrafting - 4146, -- Jocaste - 5153, -- Jormund Stonebrow - 17634, -- K. Lee Smallfry - 4563, -- Kaal Soulreaper - 8144, -- Kulleg Stonehorn - 7866, -- Peter Galen - 1386, -- Rogvar - 5564, -- Simon Tanner - 3607, -- Androl Oakhand - 3032, -- Beram Skychaser - 4611, -- Doctor Herbert Halsey - 4205, -- Dorion - 5515, -- Einris Brightspear - 26980, -- Eorain Dawnstrike - 29514, -- Findle Whistlesteam - 11146, -- Ironus Coldsteel - 3344, -- Kardris Dreamseeker - 26994, -- Kirea Moondancer - 30722, -- Neferatti - 30709, -- Poshken Hardbinder - 18776, -- Rorelien - 6251, -- Strahad Farsan - 19576, -- Xyrol - 17110, -- Acteon - 11865, -- Buliwyf Stonehand - 34708, -- Caitrin Ironkettle - 16681, -- Champion Bachi - 19187, -- Darmari - 19063, -- Hamanar - 29505, -- Imindril Spearsong - 33615, -- Inscription - 26962, -- Jonathan Lewis - 3365, -- Karolek - 26952, -- Kristen Smythe - 33618, -- Skinning - 30716, -- Thoth - 1241, -- Tognus Flintfire - 11867, -- Woo Ping - 20914, -- Aalun - 4568, -- Anastasia Hartwell - 3373, -- Arnok - 5149, -- Brandur Ironhammer - 6387, -- Dranh - 5157, -- Gimble Thistlefuzz - 376, -- High Priestess Laurena - 15280, -- Jesthenis Sunstriker - 3690, -- Kar Stormsinger - 26903, -- Lanolis Dewdrop - 2485, -- Larimaine Purdue - 1651, -- Lee Brown - 19340, -- Mi'irku Farstep - 3067, -- Pyall Silentstride - 7871, -- Se'Jib - 3007, -- Una - 17844, -- Vindicator Aesom - 28956, -- Warcaster Fanoraithe - 4160, -- Ainethil - 3606, -- Alanna Raveneye - 5491, -- Arthur the Faithful - 26911, -- Bernadette Dexter - 11178, -- Borgosh Corebender - 5489, -- Brother Joshua - 4211, -- Dannelor - 8306, -- Duhng - 6707, -- Fahrad - 26913, -- Frederic Burrhus - 4219, -- Fylerian Nightwing - 2704, -- Hanashi - 17513, -- Harnan - 19185, -- Jack Trapper - 4753, -- Jartsam - 5499, -- Lilyssia Nightbreeze - 928, -- Lord Grayson Shadowbreaker - 28472, -- Lord Thorval - 3357, -- Makaru - 30711, -- Margaux Parchley - 906, -- Maximillian Crowe - 11401, -- Priestess Alathea - 3401, -- Shenthul - 17219, -- Sulaa - 7867, -- Thorkaf Dragoneye - 26907, -- Tisha Longbridge - 6018, -- Ur'kyo - 7953, -- Xar'Ti - 4606, -- Aelthalyste - 16646, -- Alamma - 15501, -- Aleinia - 17424, -- Anchorite Paetheus - 6291, -- Balthus Stoneflayer - 17120, -- Behomat - 3001, -- Brek Stonehoof - 3601, -- Dazalar - 26954, -- Emil Autumn - 33621, -- First Aid - 3181, -- Fremal Doohickey - 1470, -- Ghak Healtouch - 1231, -- Grif Wildheart - 16653, -- Inethven - 12961, -- Kil'Hiwana - 2130, -- Marion Call - 2329, -- Michelle Belle - 19184, -- Mildred Fletcher - 3352, -- Ormak Grimshot - 18748, -- Ruak Stronghorn - 35281, -- Rukua - 7868, -- Sarah Tanner - 2327, -- Shaina Fuller - 16703, -- Amin - 27029, -- Apothecary Wormwick - 5493, -- Arnold Leland - 4156, -- Astaia - 16669, -- Bemarrin - 5144, -- Bink - 5690, -- Clyde Kellen - 3965, -- Cylania Rootstalker - 1103, -- Eldrin - 5498, -- Elsharin - 4254, -- Geofram Bouldertoe - 5164, -- Grumnus Steelshaper - 986, -- Haromm - 17509, -- Jol - 4576, -- Josef Gregorian - 4578, -- Josephine Lister - 3175, -- Krunn - 3964, -- Kylanna - 27705, -- Lorrin Foxfire - 1317, -- Lucan Cordell - 3704, -- Mahani - 2834, -- Myizz Luckycatch - 16275, -- Noellene - 16726, -- Ockil - 33591, -- Rekka the Hammer - 3030, -- Siln Skychaser - 2818, -- Slagg - 3354, -- Sorek - 5511, -- Therum Deepforge - 7088, -- Thuwd - 5479, -- Wu Shen - 1215, -- Alchemist Mallory - 22477, -- Anchorite Ensham - 4595, -- Baltus Fowler - 3009, -- Bena Winterhoof - 5484, -- Brother Benjamin - 34710, -- Ellen Moore - 23127, -- Farseer Javad - 17089, -- Firmanvaar - 5161, -- Grimnur Stonebrand - 16773, -- Handiir - 1411, -- Ian Strom - 9584, -- Jalane Ayrole - 3555, -- Johan Focht - 3028, -- Kah Mistrunner - 3170, -- Kaplak - 5492, -- Katherine the Pure - 18747, -- Krugosh - 12030, -- Malux - 29507, -- Manfred Staller - 26958, -- Marjory Kains - 7089, -- Mooranta - 29509, -- Namha Moonwater - 5116, -- Olmin Burningbeard - 18804, -- Prospector Nachlan - 3407, -- Sian'dur - 4163, -- Syurna - 3011, -- Teg Dawnstrider - 1430, -- Tomas - 5147, -- Valgar Highforge - 8738, -- Vazario Linkgrease - 5939, -- Vira Younghoof - 3967, -- Aayndia Floralwind - 16728, -- Akham - 3593, -- Alyissia - 16660, -- Belestra - 16663, -- Belil - 7946, -- Brannock - 2132, -- Carolai Anise - 33619, -- Cooking - 16667, -- Danwe - 7312, -- Dink - 17005, -- Duelist Larenis - 26906, -- Elizabeth Jackson - 20407, -- Farseer Umbrua - 5127, -- Fimble Finespindle - 16712, -- Ganaar - 3353, -- Grezz Ragefist - 4193, -- Grondal Moonbreeze - 17520, -- Gurrag - 3179, -- Harold Riggs - 6306, -- Helene Peltskinner - 2998, -- Karn Stonehoof - 988, -- Kartosh - 4616, -- Lavinia Crowe - 23128, -- Master Pyreanor - 3184, -- Miao'zan - 2489, -- Milstaff Stormeye - 17442, -- Moordo - 5150, -- Nissa Firestone - 375, -- Priestess Anetta - 3041, -- Torm Ragetotem - 5880, -- Un'Thuwa - 6295, -- Wilma Ranthal - 16651, -- Zaedana - 8308, -- Alenndaar Lapidaar - 34785, -- Alnar Whitebough - 26564, -- Borus Ironbender - 4598, -- Brom Killian - 4582, -- Carolyn Ward - 3963, -- Danlaar Nightstride - 6292, -- Eladriel - 4204, -- Firodren Mooncaller - 3594, -- Frahun Shadewhisper - 16270, -- Hannovia - 3039, -- Holt Thunderhorn - 4596, -- James Van Brunt - 3038, -- Kary Thunderhorn - 20124, -- Kradu Grimblade - 33581, -- Kul'de - 3036, -- Kym Wildmane - 5941, -- Lau'Tiki - 13283, -- Lord Tony Romano - 5506, -- Maldryn - 11177, -- Okothos Ironrager - 29506, -- Orland Schaeffer - 5166, -- Ormyr Flinteye - 2798, -- Pand Stonebinder - 5943, -- Rawrk - 16633, -- Sedana - 3595, -- Shanda - 16647, -- Talionia - 5177, -- Tally Berryfizz - 5566, -- Tannysa - 16271, -- Telenus - 895, -- Thorgas Grimson - 3171, -- Thotar - 5958, -- Thuul - 3033, -- Turak Runetotem - 16692, -- Tyn - 6290, -- Yonn Deepcut - 6286, -- Zarrin - 16771, -- Ahonan - 2856, -- Angrun - 2390, -- Aranae Venomblood - 23534, -- Babagaya Shadowcleft - 5148, -- Beldruk Doombrow - 29924, -- Brandig - 1702, -- Bronk Guzzlegear - 26960, -- Carter Tiffens - 7870, -- Caryssia Moonhunter - 16266, -- Celoenus - 3174, -- Dwukk - 19251, -- Enchantress Volali - 5883, -- Enyo - 17487, -- Erin Kelly - 17204, -- Farseer Nobundo - 2114, -- Faruza - 3345, -- Godan - 17441, -- Gurf - 16675, -- Halthenis - 3620, -- Harruk - 1218, -- Herbalist Pomeroy - 5165, -- Hulfdan Blackbeard - 11866, -- Ilyenia Moonfire - 5145, -- Juli Stormkettle - 7231, -- Kelgruk Bloodaxe - 3707, -- Ken'jai - 3013, -- Komin Winterhoof - 3363, -- Magar - 1228, -- Magis Sparkmantle - 3604, -- Malorne Bladeleaf - 985, -- Malosh - 944, -- Marryk Nurribit - 34711, -- Mary Allerton - 17434, -- Morae - 16654, -- Narinth - 3066, -- Narm Skychaser - 16679, -- Osselan - 16276, -- Ponaris - 2127, -- Rupert Boch - 3157, -- Shikrik - 4213, -- Taladan - 16279, -- Tannaria - 5171, -- Thistleheart - 5516, -- Ulfir Ironbeard - 3048, -- Ursyn Ghull - 7311, -- Uthel'nay - 5695, -- Vance Undergloom - 16684, -- Zelanis - 460, -- Alamar Grimm - 29508, -- Andellion - 4090, -- Astarii Starseeker - 16501, -- Aurelon - 2131, -- Austil de Mon - 16761, -- Baatun - 33587, -- Bethany Cromwell - 5142, -- Braenna Flintcrag - 5172, -- Briarthorn - 8141, -- Captain Evencane - 16736, -- Cemmorhan - 3545, -- Claude Erksine - 1701, -- Dank Drizzlecut - 7315, -- Darnath Bladesinger - 6299, -- Delfrum Flintbeard - 23103, -- Derek the Undying - 16738, -- Deremiis - 16749, -- Edirah - 16685, -- Elara - 26910, -- Fayin Whisperleaf - 5167, -- Fenthwick - 5612, -- Gimrizz Shadowcog - 1229, -- Granis Swiftaxe - 16655, -- Harene Plainwalker - 10086, -- Hesuwa Thunderhorn - 11406, -- High Priest Rohan - 2124, -- Isabella - 3404, -- Jandi - 6288, -- Jayla - 11037, -- Jenna Lemkenilli - 33589, -- Joseph Wilson - 27034, -- Josric Fame - 15279, -- Julia Sunstriker - 4566, -- Kaelystia Hatebringer - 5501, -- Kaerbrus - 16499, -- Keilnei - 3484, -- Kil'hala - 3061, -- Lanka Farshot - 4092, -- Lariia - 5518, -- Lilliam Sparkspindle - 16659, -- Lotheolan - 3332, -- Lumak - 34714, -- Mahara Goldwheat - 5884, -- Mai'ah - 4591, -- Mary Edras - 4583, -- Miles Dexter - 3325, -- Mirket - 1382, -- Mudduk - 16686, -- Nerisen - 5146, -- Nittlebur Sparkfizzle - 918, -- Osborne the Night Man - 15285, -- Pathstalker Avokor - 1700, -- Paxton Ganter - 5882, -- Pephredo - 8128, -- Pikkle - 3688, -- Reban Freerunner - 16763, -- Remere - 34712, -- Roberta Carter - 3155, -- Rwag - 5496, -- Sandahl - 17481, -- Semid - 16721, -- Shalannius - 916, -- Solm Hargrin - 1458, -- Telurinon Moonshadow - 5517, -- Thorfin Stoneshield - 17212, -- Tuluun - 3040, -- Urek Thunderhorn - 5495, -- Ursula Deline - 16500, -- Valaatu - 17122, -- Vord - 1683, -- Warg Deepwater - 3406, -- Xor'juul - 5392, -- Yarr Hammerstone - 328, -- Zaldimar Wefhellt - 16648, -- Zanien - 1632, -- Adele Fielder - 4900, -- Alchemist Narett - 28474, -- Amal'thazad - 17214, -- Anchorite Fateema - 4215, -- Anishar - 27023, -- Apothecary Bressa - 16161, -- Arcanist Sheynathren - 3047, -- Archmage Shymm - 4573, -- Armand Cromwell - 3596, -- Ayanna Everstride - 10090, -- Belia Thundergranite - 5957, -- Birgitte Cranston - 13084, -- Bixi Wobblebonk - 7232, -- Borgus Steelhand - 16644, -- Botanist Nathera - 3523, -- Bowen Brisboise - 837, -- Branstock Khalder - 1385, -- Brawn - 1681, -- Brock Stoneseeker - 8140, -- Brother Karman - 925, -- Brother Sammuel - 927, -- Brother Wilhelm - 2128, -- Cain Firesong - 16642, -- Camberon - 20406, -- Champion Cyssa Dawnrose - 3136, -- Clarise Gnarltree - 1355, -- Cook Ghilm - 3087, -- Crystal Boughman - 3603, -- Cyndra Kindwhisper - 5115, -- Daera Brightspear - 2119, -- Dannal Stern - 10930, -- Dargh Trueaim - 2122, -- David Trias - 461, -- Demisette Cloyce - 3172, -- Dhugru Gorelust - 16780, -- Drathen - 459, -- Drusilla La Salle - 17488, -- Dulvi - 4214, -- Erion Shadewhisper - 4552, -- Eunice Burch - 17511, -- Fallat - 4608, -- Father Lazarus - 19478, -- Fera Palerunner - 1676, -- Finbus Geargrind - 11031, -- Franklin Lloyd - 16269, -- Garridel - 3327, -- Gest - 2627, -- Grarnik Goodstitch - 21087, -- Grikka - 3324, -- Grol'dar - 17482, -- Guvan - 17519, -- Hobahken - 33641, -- Irduil - 16680, -- Ithelis - 4091, -- Jandria - 8142, -- Jannos Lighthoof - 4138, -- Jeen'ra Nightrunner - 3154, -- Jen'shan - 3602, -- Kal - 16272, -- Kanaria - 2879, -- Karrina Mekenda - 16640, -- Keelen Sheets - 3306, -- Keldas - 1901, -- Kelstrum Stonebreaker - 5113, -- Kelv Sternhammer - 917, -- Keryn Sylvius - 198, -- Khelden Bremen - 17505, -- Killac - 7087, -- Killian Hagey - 16503, -- Kore - 1404, -- Kragg - 3063, -- Krang Stonehoof - 6297, -- Kurdram Stonehammer - 28471, -- Lady Alistra - 2492, -- Lexington Mortaim - 911, -- Llane Beshere - 29196, -- Lord Thorval - 12032, -- Lui'Mala - 4564, -- Luther Pickman - 16688, -- Lynalis - 913, -- Lyria Du Lac - 331, -- Maginor Dumas - 16160, -- Magistrix Eredania - 1292, -- Maris Granger - 3137, -- Matt Johnson - 1680, -- Matthew Hooper - 1226, -- Maxan Anvol - 2126, -- Maximillion - 4159, -- Me'lynn - 3062, -- Meela Dawnstrider - 16724, -- Miall - 3185, -- Mishiki - 16752, -- Muaat - 16719, -- Mumman - 3605, -- Nadyia Maneweaver - 16725, -- Nahogg - 543, -- Nalesette Wildbringer - 3156, -- Nartok - 8153, -- Narv Hidecrafter - 987, -- Ogromm - 33590, -- Oluros - 3328, -- Ormok - 4567, -- Pierce Shackleton - 377, -- Priestess Josetta - 16277, -- Quarelestra - 16652, -- Quithas - 6289, -- Rand Rhobart - 15513, -- Ranger Sallina - 5117, -- Regnus Thundergranite - 5137, -- Reyna Stonebranch - 4565, -- Richard Kerwin - 17480, -- Ruada - 8146, -- Ruw - 13417, -- Sagorne Creststrider - 2391, -- Serge Hinott - 19180, -- Seymour - 5502, -- Shylamiir - 4089, -- Sildanair - 10089, -- Silvaria - 15283, -- Summoner Teli'Larien - 3173, -- Swart - 16672, -- Tana - 3169, -- Tarshaw Jaggedscar - 5141, -- Theodrus Frostbeard - 5505, -- Theridran - 3049, -- Thurston Xane - 3031, -- Tigor Skychaser - 5143, -- Toldren Deepiron - 10993, -- Twizwick Sprocketgrind - 6014, -- X'yera - 3065, -- Yaw Sharpmane - 16674, -- Zandine - 5994, -- Zayus - 3624, -- Zudd - 16658, -- Aldrae - 4210, -- Alegorn - 16662, -- Alestus - 812, -- Alma Jainrose - 914, -- Ander Germaine - 4594, -- Angela Curthas - 4087, -- Arias'ta Bladesinger - 17514, -- Bati - 11068, -- Betty Quin - 5114, -- Bilban Tosslespanner - 3698, -- Bolyun - 4898, -- Brant Jasperbloom - 926, -- Bromos Grummner - 17484, -- Buruk - 6094, -- Byancie - 16756, -- Caedmos - 4320, -- Caelyb - 19369, -- Celie Steelwing - 3069, -- Chaw Stronghide - 4593, -- Christoph Walker - 17215, -- Daedal - 2129, -- Dark Cleric Beryl - 2123, -- Dark Cleric Duesten - 3290, -- Deek Fizzlebizz - 2367, -- Donald Rabonne - 17105, -- Emissary Valustraa - 16774, -- Erett - 3046, -- Father Cobb - 4607, -- Father Lankester - 908, -- Flora Silverwind - 3153, -- Frang - 3060, -- Gart Mistrunner - 9465, -- Golhine the Hooded - 4584, -- Gregory Charles - 1699, -- Gremlock Pilsnor - 3622, -- Grokor - 19341, -- Grutah - 3557, -- Guillaume Sorouy - 3059, -- Harutt Thunderhorn - 17983, -- Heur - 1234, -- Hogral Bakkan - 27704, -- Horace Alder - 5480, -- Ilsa Corbin - 17510, -- Izmir - 3599, -- Jannok Breezesong - 915, -- Jorik Kerridan - 1473, -- Kali Healtouch - 17121, -- Kavaan - 17504, -- Kazi - 3043, -- Ker Ragetotem - 3703, -- Krulmoo Fullmoon - 3598, -- Kyra Windblade - 3600, -- Laurna Morninglight - 16723, -- Lucc - 16755, -- Lunaraa - 3045, -- Malakai Cross - 12025, -- Malvor - 3597, -- Mardant Strongoak - 4614, -- Martha Alliestar - 16273, -- Mathreyn - 15284, -- Matron Arena - 11025, -- Mukdrak - 11397, -- Nara Meideros - 5759, -- Nurse Neela - 16731, -- Nus - 16673, -- Oninath - 2878, -- Peria Lamenur - 16729, -- Refik - 3042, -- Sark Ragetotem - 16278, -- Sathein - 7230, -- Shayis Steelfury - 3034, -- Sheal Runetotem - 3549, -- Shelene Rhobart - 3403, -- Sian'tsu - 514, -- Smith Argus - 16676, -- Sylann - 3706, -- Tai'jin - 3004, -- Tepa - 2326, -- Thamner Pol - 912, -- Thran Khorman - 3478, -- Traugh - 17483, -- Tullas - 5784, -- Waldor - 10088, -- Xao'tsu - 7949, -- Xylinnia Starshine - 16502, -- Zalduun - 3408, -- Zel'mak - 20125, -- Zula Slagfury + [MINIMAP_TRACKING_TRAINER_PROFESSION] = { + [29156] = true, -- Archmage Celindra + [28697] = true, -- Timofey Oshenko + [35135] = true, -- Wind Rider Sabamba + [28699] = true, -- Charles Worth + [28746] = true, -- Pilot Vic + [4752] = true, -- Kildar + [35093] = true, -- Wind Rider Jahubo + [26953] = true, -- Thomas Kolichio + [26905] = true, -- Brom Brewbaster + [26986] = true, -- Tiponi Stormwhisper + [28705] = true, -- Katherine Lee + [26989] = true, -- Rollick MacKreel + [28703] = true, -- Linzy Blackbolt + [26972] = true, -- Orn Tenderhoof + [29631] = true, -- Awilo Lon'gomba + [26992] = true, -- Brynna Wilson + [33586] = true, -- Binkie Brightgear + [35100] = true, -- Hargen Bronzewing + [28706] = true, -- Olisarra the Kind + [11073] = true, -- Annora + [8736] = true, -- Buzzek Bracketswing + [35133] = true, -- Maigra Keenfeather + [26964] = true, -- Alexandra McQueen + [26996] = true, -- Awan Iceborn + [27001] = true, -- Darin Goodstitch + [8126] = true, -- Nixx Sprocketspring + [26993] = true, -- Old Man Robert + [4732] = true, -- Randal Hunter + [26997] = true, -- Alestos + [26976] = true, -- Brunna Ironaxe + [28698] = true, -- Jedidiah Handers + [28702] = true, -- Professor Pallin + [25099] = true, -- Jonathan Garrett + [33623] = true, -- Fishing + [5174] = true, -- Springspindle Fizzlegear + [30713] = true, -- Catarina Stanford + [33613] = true, -- Tailoring + [26991] = true, -- Sock Brightbolt + [3494] = true, -- Tinkerwiz + [28694] = true, -- Alard Schmied + [4212] = true, -- Telonis + [25277] = true, -- Chief Engineer Leveny + [33580] = true, -- Dustin Vail + [3064] = true, -- Gennia Runetotem + [33616] = true, -- Herbalism + [26969] = true, -- Raenah + [4772] = true, -- Ultham Ironhorn + [26975] = true, -- Arthur Henslowe + [11868] = true, -- Sayoc + [11052] = true, -- Timothy Worthington + [26999] = true, -- Fendrig Redbeard + [12042] = true, -- Loganaar + [24868] = true, -- Niobe Whizzlespark + [33611] = true, -- Engineering + [2836] = true, -- Brikk Keencraft + [7406] = true, -- Oglethorpe Obnoticus + [27000] = true, -- Trapper Jack + [11097] = true, -- Drakk Stonehand + [19778] = true, -- Farii + [1346] = true, -- Georgio Bolero + [29233] = true, -- Nurse Applewood + [16280] = true, -- Perascamin + [26974] = true, -- Tansy Wildmane + [4773] = true, -- Velma Warnam + [28693] = true, -- Enchanter Nalthanis + [19052] = true, -- Lorokeem + [26998] = true, -- Rosemary Bovard + [23734] = true, -- Anchorite Yazmina + [11869] = true, -- Ansekhwa + [31084] = true, -- Highlord Darion Mograine + [18779] = true, -- Hurnak Grimmord + [30706] = true, -- Jo'mah + [7869] = true, -- Brumn Winterhoof + [33610] = true, -- Enchanting + [5159] = true, -- Daryl Riknussun + [28704] = true, -- Dorothy Egan + [26912] = true, -- Grumbol Stoutpick + [33617] = true, -- Mining + [7944] = true, -- Tinkmaster Overspark + [18777] = true, -- Jelena Nightsky + [2399] = true, -- Daryl Stack + [28696] = true, -- Derik Marks + [26955] = true, -- Jamesina Watterly + [17637] = true, -- Mack Diver + [11017] = true, -- Roxxik + [26914] = true, -- Benjamin Clegg + [30717] = true, -- Elise Brightletter + [30715] = true, -- Feyden Darkin + [26956] = true, -- Sally Tompkins + [26957] = true, -- Angelina Soren + [26909] = true, -- Byron Welwick + [26982] = true, -- Geba'li + [11098] = true, -- Hahrana Ironhide + [28700] = true, -- Diane Cannings + [26961] = true, -- Gunter Hansen + [7948] = true, -- Kylanna Windwhisper + [6287] = true, -- Radnaal Maneweaver + [5482] = true, -- Stephen Ryback + [7954] = true, -- Binjy Featherwhistle + [19775] = true, -- Kalinda + [4258] = true, -- Bengus Deepforge + [19252] = true, -- High Enchanter Bardolan + [26915] = true, -- Ounhulo + [26963] = true, -- Roberta Jacks + [26990] = true, -- Alexis Marlowe + [5885] = true, -- Deino + [33583] = true, -- Fael Morningsong + [26987] = true, -- Falorn Nightwhisper + [5513] = true, -- Gelman Stonehand + [5497] = true, -- Jennea Cannon + [18755] = true, -- Moorutu + [11870] = true, -- Archibald + [26988] = true, -- Argo Strongstout + [26981] = true, -- Crog Steelspine + [33588] = true, -- Crystal Brightspark + [20791] = true, -- Iorioa + [29195] = true, -- Lady Alistra + [34713] = true, -- Ondani Greatmill + [26904] = true, -- Rosina Rivet + [5938] = true, -- Uthan Stillwater + [29194] = true, -- Amal'thazad + [11074] = true, -- Hgarth + [28958] = true, -- Jessa Weaver + [11072] = true, -- Kitta Firewind + [33612] = true, -- Leatherworking + [3355] = true, -- Saru Steelfury + [5504] = true, -- Sheldras Moontree + [26951] = true, -- Wilhelmina Renel + [3399] = true, -- Zamja + [3026] = true, -- Aska Mistrunner + [1232] = true, -- Azar Stronghammer + [4218] = true, -- Denatharion + [32474] = true, -- Fishy Ser'ji + [2837] = true, -- Jaxin Chong + [30721] = true, -- Michael Schwan + [20500] = true, -- Olrokk + [27703] = true, -- Ysuria + [30710] = true, -- Zantasia + [33603] = true, -- Arthur Denny + [4588] = true, -- Arthur Moore + [33609] = true, -- Blacksmithing + [3347] = true, -- Yelmak + [3326] = true, -- Zevrost + [33608] = true, -- Alchemy + [29513] = true, -- Didi the Wrench + [16621] = true, -- Ileda + [20511] = true, -- Ilsa Blusterbrew + [33614] = true, -- Jewelcrafting + [4146] = true, -- Jocaste + [5153] = true, -- Jormund Stonebrow + [17634] = true, -- K. Lee Smallfry + [4563] = true, -- Kaal Soulreaper + [8144] = true, -- Kulleg Stonehorn + [7866] = true, -- Peter Galen + [1386] = true, -- Rogvar + [5564] = true, -- Simon Tanner + [3607] = true, -- Androl Oakhand + [3032] = true, -- Beram Skychaser + [4611] = true, -- Doctor Herbert Halsey + [4205] = true, -- Dorion + [5515] = true, -- Einris Brightspear + [26980] = true, -- Eorain Dawnstrike + [29514] = true, -- Findle Whistlesteam + [11146] = true, -- Ironus Coldsteel + [3344] = true, -- Kardris Dreamseeker + [26994] = true, -- Kirea Moondancer + [30722] = true, -- Neferatti + [30709] = true, -- Poshken Hardbinder + [18776] = true, -- Rorelien + [6251] = true, -- Strahad Farsan + [19576] = true, -- Xyrol + [17110] = true, -- Acteon + [11865] = true, -- Buliwyf Stonehand + [34708] = true, -- Caitrin Ironkettle + [16681] = true, -- Champion Bachi + [19187] = true, -- Darmari + [19063] = true, -- Hamanar + [29505] = true, -- Imindril Spearsong + [33615] = true, -- Inscription + [26962] = true, -- Jonathan Lewis + [3365] = true, -- Karolek + [26952] = true, -- Kristen Smythe + [33618] = true, -- Skinning + [30716] = true, -- Thoth + [1241] = true, -- Tognus Flintfire + [11867] = true, -- Woo Ping + [20914] = true, -- Aalun + [4568] = true, -- Anastasia Hartwell + [3373] = true, -- Arnok + [5149] = true, -- Brandur Ironhammer + [6387] = true, -- Dranh + [5157] = true, -- Gimble Thistlefuzz + [376] = true, -- High Priestess Laurena + [15280] = true, -- Jesthenis Sunstriker + [3690] = true, -- Kar Stormsinger + [26903] = true, -- Lanolis Dewdrop + [2485] = true, -- Larimaine Purdue + [1651] = true, -- Lee Brown + [19340] = true, -- Mi'irku Farstep + [3067] = true, -- Pyall Silentstride + [7871] = true, -- Se'Jib + [3007] = true, -- Una + [17844] = true, -- Vindicator Aesom + [28956] = true, -- Warcaster Fanoraithe + [4160] = true, -- Ainethil + [3606] = true, -- Alanna Raveneye + [5491] = true, -- Arthur the Faithful + [26911] = true, -- Bernadette Dexter + [11178] = true, -- Borgosh Corebender + [5489] = true, -- Brother Joshua + [4211] = true, -- Dannelor + [8306] = true, -- Duhng + [6707] = true, -- Fahrad + [26913] = true, -- Frederic Burrhus + [4219] = true, -- Fylerian Nightwing + [2704] = true, -- Hanashi + [17513] = true, -- Harnan + [19185] = true, -- Jack Trapper + [4753] = true, -- Jartsam + [5499] = true, -- Lilyssia Nightbreeze + [928] = true, -- Lord Grayson Shadowbreaker + [28472] = true, -- Lord Thorval + [3357] = true, -- Makaru + [30711] = true, -- Margaux Parchley + [906] = true, -- Maximillian Crowe + [11401] = true, -- Priestess Alathea + [3401] = true, -- Shenthul + [17219] = true, -- Sulaa + [7867] = true, -- Thorkaf Dragoneye + [26907] = true, -- Tisha Longbridge + [6018] = true, -- Ur'kyo + [7953] = true, -- Xar'Ti + [4606] = true, -- Aelthalyste + [16646] = true, -- Alamma + [15501] = true, -- Aleinia + [17424] = true, -- Anchorite Paetheus + [6291] = true, -- Balthus Stoneflayer + [17120] = true, -- Behomat + [3001] = true, -- Brek Stonehoof + [3601] = true, -- Dazalar + [26954] = true, -- Emil Autumn + [33621] = true, -- First Aid + [3181] = true, -- Fremal Doohickey + [1470] = true, -- Ghak Healtouch + [1231] = true, -- Grif Wildheart + [16653] = true, -- Inethven + [12961] = true, -- Kil'Hiwana + [2130] = true, -- Marion Call + [2329] = true, -- Michelle Belle + [19184] = true, -- Mildred Fletcher + [3352] = true, -- Ormak Grimshot + [18748] = true, -- Ruak Stronghorn + [35281] = true, -- Rukua + [7868] = true, -- Sarah Tanner + [2327] = true, -- Shaina Fuller + [16703] = true, -- Amin + [27029] = true, -- Apothecary Wormwick + [5493] = true, -- Arnold Leland + [4156] = true, -- Astaia + [16669] = true, -- Bemarrin + [5144] = true, -- Bink + [5690] = true, -- Clyde Kellen + [3965] = true, -- Cylania Rootstalker + [1103] = true, -- Eldrin + [5498] = true, -- Elsharin + [4254] = true, -- Geofram Bouldertoe + [5164] = true, -- Grumnus Steelshaper + [986] = true, -- Haromm + [17509] = true, -- Jol + [4576] = true, -- Josef Gregorian + [4578] = true, -- Josephine Lister + [3175] = true, -- Krunn + [3964] = true, -- Kylanna + [27705] = true, -- Lorrin Foxfire + [1317] = true, -- Lucan Cordell + [3704] = true, -- Mahani + [2834] = true, -- Myizz Luckycatch + [16275] = true, -- Noellene + [16726] = true, -- Ockil + [33591] = true, -- Rekka the Hammer + [3030] = true, -- Siln Skychaser + [2818] = true, -- Slagg + [3354] = true, -- Sorek + [5511] = true, -- Therum Deepforge + [7088] = true, -- Thuwd + [5479] = true, -- Wu Shen + [1215] = true, -- Alchemist Mallory + [22477] = true, -- Anchorite Ensham + [4595] = true, -- Baltus Fowler + [3009] = true, -- Bena Winterhoof + [5484] = true, -- Brother Benjamin + [34710] = true, -- Ellen Moore + [23127] = true, -- Farseer Javad + [17089] = true, -- Firmanvaar + [5161] = true, -- Grimnur Stonebrand + [16773] = true, -- Handiir + [1411] = true, -- Ian Strom + [9584] = true, -- Jalane Ayrole + [3555] = true, -- Johan Focht + [3028] = true, -- Kah Mistrunner + [3170] = true, -- Kaplak + [5492] = true, -- Katherine the Pure + [18747] = true, -- Krugosh + [12030] = true, -- Malux + [29507] = true, -- Manfred Staller + [26958] = true, -- Marjory Kains + [7089] = true, -- Mooranta + [29509] = true, -- Namha Moonwater + [5116] = true, -- Olmin Burningbeard + [18804] = true, -- Prospector Nachlan + [3407] = true, -- Sian'dur + [4163] = true, -- Syurna + [3011] = true, -- Teg Dawnstrider + [1430] = true, -- Tomas + [5147] = true, -- Valgar Highforge + [8738] = true, -- Vazario Linkgrease + [5939] = true, -- Vira Younghoof + [3967] = true, -- Aayndia Floralwind + [16728] = true, -- Akham + [3593] = true, -- Alyissia + [16660] = true, -- Belestra + [16663] = true, -- Belil + [7946] = true, -- Brannock + [2132] = true, -- Carolai Anise + [33619] = true, -- Cooking + [16667] = true, -- Danwe + [7312] = true, -- Dink + [17005] = true, -- Duelist Larenis + [26906] = true, -- Elizabeth Jackson + [20407] = true, -- Farseer Umbrua + [5127] = true, -- Fimble Finespindle + [16712] = true, -- Ganaar + [3353] = true, -- Grezz Ragefist + [4193] = true, -- Grondal Moonbreeze + [17520] = true, -- Gurrag + [3179] = true, -- Harold Riggs + [6306] = true, -- Helene Peltskinner + [2998] = true, -- Karn Stonehoof + [988] = true, -- Kartosh + [4616] = true, -- Lavinia Crowe + [23128] = true, -- Master Pyreanor + [3184] = true, -- Miao'zan + [2489] = true, -- Milstaff Stormeye + [17442] = true, -- Moordo + [5150] = true, -- Nissa Firestone + [375] = true, -- Priestess Anetta + [3041] = true, -- Torm Ragetotem + [5880] = true, -- Un'Thuwa + [6295] = true, -- Wilma Ranthal + [16651] = true, -- Zaedana + [8308] = true, -- Alenndaar Lapidaar + [34785] = true, -- Alnar Whitebough + [26564] = true, -- Borus Ironbender + [4598] = true, -- Brom Killian + [4582] = true, -- Carolyn Ward + [3963] = true, -- Danlaar Nightstride + [6292] = true, -- Eladriel + [4204] = true, -- Firodren Mooncaller + [3594] = true, -- Frahun Shadewhisper + [16270] = true, -- Hannovia + [3039] = true, -- Holt Thunderhorn + [4596] = true, -- James Van Brunt + [3038] = true, -- Kary Thunderhorn + [20124] = true, -- Kradu Grimblade + [33581] = true, -- Kul'de + [3036] = true, -- Kym Wildmane + [5941] = true, -- Lau'Tiki + [13283] = true, -- Lord Tony Romano + [5506] = true, -- Maldryn + [11177] = true, -- Okothos Ironrager + [29506] = true, -- Orland Schaeffer + [5166] = true, -- Ormyr Flinteye + [2798] = true, -- Pand Stonebinder + [5943] = true, -- Rawrk + [16633] = true, -- Sedana + [3595] = true, -- Shanda + [16647] = true, -- Talionia + [5177] = true, -- Tally Berryfizz + [5566] = true, -- Tannysa + [16271] = true, -- Telenus + [895] = true, -- Thorgas Grimson + [3171] = true, -- Thotar + [5958] = true, -- Thuul + [3033] = true, -- Turak Runetotem + [16692] = true, -- Tyn + [6290] = true, -- Yonn Deepcut + [6286] = true, -- Zarrin + [16771] = true, -- Ahonan + [2856] = true, -- Angrun + [2390] = true, -- Aranae Venomblood + [23534] = true, -- Babagaya Shadowcleft + [5148] = true, -- Beldruk Doombrow + [29924] = true, -- Brandig + [1702] = true, -- Bronk Guzzlegear + [26960] = true, -- Carter Tiffens + [7870] = true, -- Caryssia Moonhunter + [16266] = true, -- Celoenus + [3174] = true, -- Dwukk + [19251] = true, -- Enchantress Volali + [5883] = true, -- Enyo + [17487] = true, -- Erin Kelly + [17204] = true, -- Farseer Nobundo + [2114] = true, -- Faruza + [3345] = true, -- Godan + [17441] = true, -- Gurf + [16675] = true, -- Halthenis + [3620] = true, -- Harruk + [1218] = true, -- Herbalist Pomeroy + [5165] = true, -- Hulfdan Blackbeard + [11866] = true, -- Ilyenia Moonfire + [5145] = true, -- Juli Stormkettle + [7231] = true, -- Kelgruk Bloodaxe + [3707] = true, -- Ken'jai + [3013] = true, -- Komin Winterhoof + [3363] = true, -- Magar + [1228] = true, -- Magis Sparkmantle + [3604] = true, -- Malorne Bladeleaf + [985] = true, -- Malosh + [944] = true, -- Marryk Nurribit + [34711] = true, -- Mary Allerton + [17434] = true, -- Morae + [16654] = true, -- Narinth + [3066] = true, -- Narm Skychaser + [16679] = true, -- Osselan + [16276] = true, -- Ponaris + [2127] = true, -- Rupert Boch + [3157] = true, -- Shikrik + [4213] = true, -- Taladan + [16279] = true, -- Tannaria + [5171] = true, -- Thistleheart + [5516] = true, -- Ulfir Ironbeard + [3048] = true, -- Ursyn Ghull + [7311] = true, -- Uthel'nay + [5695] = true, -- Vance Undergloom + [16684] = true, -- Zelanis + [460] = true, -- Alamar Grimm + [29508] = true, -- Andellion + [4090] = true, -- Astarii Starseeker + [16501] = true, -- Aurelon + [2131] = true, -- Austil de Mon + [16761] = true, -- Baatun + [33587] = true, -- Bethany Cromwell + [5142] = true, -- Braenna Flintcrag + [5172] = true, -- Briarthorn + [8141] = true, -- Captain Evencane + [16736] = true, -- Cemmorhan + [3545] = true, -- Claude Erksine + [1701] = true, -- Dank Drizzlecut + [7315] = true, -- Darnath Bladesinger + [6299] = true, -- Delfrum Flintbeard + [23103] = true, -- Derek the Undying + [16738] = true, -- Deremiis + [16749] = true, -- Edirah + [16685] = true, -- Elara + [26910] = true, -- Fayin Whisperleaf + [5167] = true, -- Fenthwick + [5612] = true, -- Gimrizz Shadowcog + [1229] = true, -- Granis Swiftaxe + [16655] = true, -- Harene Plainwalker + [10086] = true, -- Hesuwa Thunderhorn + [11406] = true, -- High Priest Rohan + [2124] = true, -- Isabella + [3404] = true, -- Jandi + [6288] = true, -- Jayla + [11037] = true, -- Jenna Lemkenilli + [33589] = true, -- Joseph Wilson + [27034] = true, -- Josric Fame + [15279] = true, -- Julia Sunstriker + [4566] = true, -- Kaelystia Hatebringer + [5501] = true, -- Kaerbrus + [16499] = true, -- Keilnei + [3484] = true, -- Kil'hala + [3061] = true, -- Lanka Farshot + [4092] = true, -- Lariia + [5518] = true, -- Lilliam Sparkspindle + [16659] = true, -- Lotheolan + [3332] = true, -- Lumak + [34714] = true, -- Mahara Goldwheat + [5884] = true, -- Mai'ah + [4591] = true, -- Mary Edras + [4583] = true, -- Miles Dexter + [3325] = true, -- Mirket + [1382] = true, -- Mudduk + [16686] = true, -- Nerisen + [5146] = true, -- Nittlebur Sparkfizzle + [918] = true, -- Osborne the Night Man + [15285] = true, -- Pathstalker Avokor + [1700] = true, -- Paxton Ganter + [5882] = true, -- Pephredo + [8128] = true, -- Pikkle + [3688] = true, -- Reban Freerunner + [16763] = true, -- Remere + [34712] = true, -- Roberta Carter + [3155] = true, -- Rwag + [5496] = true, -- Sandahl + [17481] = true, -- Semid + [16721] = true, -- Shalannius + [916] = true, -- Solm Hargrin + [1458] = true, -- Telurinon Moonshadow + [5517] = true, -- Thorfin Stoneshield + [17212] = true, -- Tuluun + [3040] = true, -- Urek Thunderhorn + [5495] = true, -- Ursula Deline + [16500] = true, -- Valaatu + [17122] = true, -- Vord + [1683] = true, -- Warg Deepwater + [3406] = true, -- Xor'juul + [5392] = true, -- Yarr Hammerstone + [328] = true, -- Zaldimar Wefhellt + [16648] = true, -- Zanien + [1632] = true, -- Adele Fielder + [4900] = true, -- Alchemist Narett + [28474] = true, -- Amal'thazad + [17214] = true, -- Anchorite Fateema + [4215] = true, -- Anishar + [27023] = true, -- Apothecary Bressa + [16161] = true, -- Arcanist Sheynathren + [3047] = true, -- Archmage Shymm + [4573] = true, -- Armand Cromwell + [3596] = true, -- Ayanna Everstride + [10090] = true, -- Belia Thundergranite + [5957] = true, -- Birgitte Cranston + [13084] = true, -- Bixi Wobblebonk + [7232] = true, -- Borgus Steelhand + [16644] = true, -- Botanist Nathera + [3523] = true, -- Bowen Brisboise + [837] = true, -- Branstock Khalder + [1385] = true, -- Brawn + [1681] = true, -- Brock Stoneseeker + [8140] = true, -- Brother Karman + [925] = true, -- Brother Sammuel + [927] = true, -- Brother Wilhelm + [2128] = true, -- Cain Firesong + [16642] = true, -- Camberon + [20406] = true, -- Champion Cyssa Dawnrose + [3136] = true, -- Clarise Gnarltree + [1355] = true, -- Cook Ghilm + [3087] = true, -- Crystal Boughman + [3603] = true, -- Cyndra Kindwhisper + [5115] = true, -- Daera Brightspear + [2119] = true, -- Dannal Stern + [10930] = true, -- Dargh Trueaim + [2122] = true, -- David Trias + [461] = true, -- Demisette Cloyce + [3172] = true, -- Dhugru Gorelust + [16780] = true, -- Drathen + [459] = true, -- Drusilla La Salle + [17488] = true, -- Dulvi + [4214] = true, -- Erion Shadewhisper + [4552] = true, -- Eunice Burch + [17511] = true, -- Fallat + [4608] = true, -- Father Lazarus + [19478] = true, -- Fera Palerunner + [1676] = true, -- Finbus Geargrind + [11031] = true, -- Franklin Lloyd + [16269] = true, -- Garridel + [3327] = true, -- Gest + [2627] = true, -- Grarnik Goodstitch + [21087] = true, -- Grikka + [3324] = true, -- Grol'dar + [17482] = true, -- Guvan + [17519] = true, -- Hobahken + [33641] = true, -- Irduil + [16680] = true, -- Ithelis + [4091] = true, -- Jandria + [8142] = true, -- Jannos Lighthoof + [4138] = true, -- Jeen'ra Nightrunner + [3154] = true, -- Jen'shan + [3602] = true, -- Kal + [16272] = true, -- Kanaria + [2879] = true, -- Karrina Mekenda + [16640] = true, -- Keelen Sheets + [3306] = true, -- Keldas + [1901] = true, -- Kelstrum Stonebreaker + [5113] = true, -- Kelv Sternhammer + [917] = true, -- Keryn Sylvius + [198] = true, -- Khelden Bremen + [17505] = true, -- Killac + [7087] = true, -- Killian Hagey + [16503] = true, -- Kore + [1404] = true, -- Kragg + [3063] = true, -- Krang Stonehoof + [6297] = true, -- Kurdram Stonehammer + [28471] = true, -- Lady Alistra + [2492] = true, -- Lexington Mortaim + [911] = true, -- Llane Beshere + [29196] = true, -- Lord Thorval + [12032] = true, -- Lui'Mala + [4564] = true, -- Luther Pickman + [16688] = true, -- Lynalis + [913] = true, -- Lyria Du Lac + [331] = true, -- Maginor Dumas + [16160] = true, -- Magistrix Eredania + [1292] = true, -- Maris Granger + [3137] = true, -- Matt Johnson + [1680] = true, -- Matthew Hooper + [1226] = true, -- Maxan Anvol + [2126] = true, -- Maximillion + [4159] = true, -- Me'lynn + [3062] = true, -- Meela Dawnstrider + [16724] = true, -- Miall + [3185] = true, -- Mishiki + [16752] = true, -- Muaat + [16719] = true, -- Mumman + [3605] = true, -- Nadyia Maneweaver + [16725] = true, -- Nahogg + [543] = true, -- Nalesette Wildbringer + [3156] = true, -- Nartok + [8153] = true, -- Narv Hidecrafter + [987] = true, -- Ogromm + [33590] = true, -- Oluros + [3328] = true, -- Ormok + [4567] = true, -- Pierce Shackleton + [377] = true, -- Priestess Josetta + [16277] = true, -- Quarelestra + [16652] = true, -- Quithas + [6289] = true, -- Rand Rhobart + [15513] = true, -- Ranger Sallina + [5117] = true, -- Regnus Thundergranite + [5137] = true, -- Reyna Stonebranch + [4565] = true, -- Richard Kerwin + [17480] = true, -- Ruada + [8146] = true, -- Ruw + [13417] = true, -- Sagorne Creststrider + [2391] = true, -- Serge Hinott + [19180] = true, -- Seymour + [5502] = true, -- Shylamiir + [4089] = true, -- Sildanair + [10089] = true, -- Silvaria + [15283] = true, -- Summoner Teli'Larien + [3173] = true, -- Swart + [16672] = true, -- Tana + [3169] = true, -- Tarshaw Jaggedscar + [5141] = true, -- Theodrus Frostbeard + [5505] = true, -- Theridran + [3049] = true, -- Thurston Xane + [3031] = true, -- Tigor Skychaser + [5143] = true, -- Toldren Deepiron + [10993] = true, -- Twizwick Sprocketgrind + [6014] = true, -- X'yera + [3065] = true, -- Yaw Sharpmane + [16674] = true, -- Zandine + [5994] = true, -- Zayus + [3624] = true, -- Zudd + [16658] = true, -- Aldrae + [4210] = true, -- Alegorn + [16662] = true, -- Alestus + [812] = true, -- Alma Jainrose + [914] = true, -- Ander Germaine + [4594] = true, -- Angela Curthas + [4087] = true, -- Arias'ta Bladesinger + [17514] = true, -- Bati + [11068] = true, -- Betty Quin + [5114] = true, -- Bilban Tosslespanner + [3698] = true, -- Bolyun + [4898] = true, -- Brant Jasperbloom + [926] = true, -- Bromos Grummner + [17484] = true, -- Buruk + [6094] = true, -- Byancie + [16756] = true, -- Caedmos + [4320] = true, -- Caelyb + [19369] = true, -- Celie Steelwing + [3069] = true, -- Chaw Stronghide + [4593] = true, -- Christoph Walker + [17215] = true, -- Daedal + [2129] = true, -- Dark Cleric Beryl + [2123] = true, -- Dark Cleric Duesten + [3290] = true, -- Deek Fizzlebizz + [2367] = true, -- Donald Rabonne + [17105] = true, -- Emissary Valustraa + [16774] = true, -- Erett + [3046] = true, -- Father Cobb + [4607] = true, -- Father Lankester + [908] = true, -- Flora Silverwind + [3153] = true, -- Frang + [3060] = true, -- Gart Mistrunner + [9465] = true, -- Golhine the Hooded + [4584] = true, -- Gregory Charles + [1699] = true, -- Gremlock Pilsnor + [3622] = true, -- Grokor + [19341] = true, -- Grutah + [3557] = true, -- Guillaume Sorouy + [3059] = true, -- Harutt Thunderhorn + [17983] = true, -- Heur + [1234] = true, -- Hogral Bakkan + [27704] = true, -- Horace Alder + [5480] = true, -- Ilsa Corbin + [17510] = true, -- Izmir + [3599] = true, -- Jannok Breezesong + [915] = true, -- Jorik Kerridan + [1473] = true, -- Kali Healtouch + [17121] = true, -- Kavaan + [17504] = true, -- Kazi + [3043] = true, -- Ker Ragetotem + [3703] = true, -- Krulmoo Fullmoon + [3598] = true, -- Kyra Windblade + [3600] = true, -- Laurna Morninglight + [16723] = true, -- Lucc + [16755] = true, -- Lunaraa + [3045] = true, -- Malakai Cross + [12025] = true, -- Malvor + [3597] = true, -- Mardant Strongoak + [4614] = true, -- Martha Alliestar + [16273] = true, -- Mathreyn + [15284] = true, -- Matron Arena + [11025] = true, -- Mukdrak + [11397] = true, -- Nara Meideros + [5759] = true, -- Nurse Neela + [16731] = true, -- Nus + [16673] = true, -- Oninath + [2878] = true, -- Peria Lamenur + [16729] = true, -- Refik + [3042] = true, -- Sark Ragetotem + [16278] = true, -- Sathein + [7230] = true, -- Shayis Steelfury + [3034] = true, -- Sheal Runetotem + [3549] = true, -- Shelene Rhobart + [3403] = true, -- Sian'tsu + [514] = true, -- Smith Argus + [16676] = true, -- Sylann + [3706] = true, -- Tai'jin + [3004] = true, -- Tepa + [2326] = true, -- Thamner Pol + [912] = true, -- Thran Khorman + [3478] = true, -- Traugh + [17483] = true, -- Tullas + [5784] = true, -- Waldor + [10088] = true, -- Xao'tsu + [7949] = true, -- Xylinnia Starshine + [16502] = true, -- Zalduun + [3408] = true, -- Zel'mak + [20125] = true, -- Zula Slagfury }, - ["Vendor"] = { - 5594, -- Alchemist Pestlezugg - 8137, -- Gikkix - 2685, -- Mazk Snipeshot - 14846, -- Lhara - 12022, -- Lorelae Wintersong - 7947, -- Vivianna - 3556, -- Andrew Hilbert - 340, -- Kendor Kabonka - 12919, -- Nat Pagle - 2806, -- Bale - 1465, -- Drac Roughcut - 2664, -- Kelsey Yance - 8145, -- Sheendra Tallgrass - 4561, -- Daniel Bartlett - 8139, -- Jabbey - 1448, -- Neal Allen - 8125, -- Dirge Quikcleave - 4229, -- Mythrin'dir - 66, -- Tharynn Bouden - 2821, -- Keena - 15419, -- Kania - 11056, -- Alchemist Arbington - 5494, -- Catherine Leland - 4877, -- Jandia - 9499, -- Plugger Spazzring - 12944, -- Lokhtos Darkbargainer - 2803, -- Malygen - 3362, -- Ogunaro Wolfrunner - 11189, -- Qia - 8666, -- Lil Timmy - 3482, -- Tari'qa - 7564, -- Marin Noggenfogger - 16786, -- Argent Quartermaster - 12781, -- Master Sergeant Biggins - 2810, -- Hammon Karwn - 12245, -- Vendor-Tron 1000 - 3955, -- Shandrina - 12246, -- Super-Seller 680 - 3489, -- Zargh - 15174, -- Calandrath - 12043, -- Kulwia - 15351, -- Alliance Brigadier General - 8401, -- Halpa - 6548, -- Magus Tirth - 4585, -- Ezekiel Graves - 1326, -- Sloan McCoy - 5162, -- Tansy Puddlefizz - 12033, -- Wulan - 17598, -- Renn'az - 3546, -- Bernie Heisten - 483, -- Elaine Trias - 11188, -- Evie Whirlbrew - 3443, -- Grub - 14847, -- Professor Thaddeus Paleo - 4453, -- Wizzle Brassbolts - 11185, -- Xizzer Fizzbolt - 1263, -- Yarlyn Amberstill - 5175, -- Gearcutter Cogspinner - 2848, -- Glyx Brewright - 11557, -- Meilosh - 2663, -- Narkk - 5817, -- Shimra - 2480, -- Bro'kin - 4897, -- Helenia Olden - 8679, -- Knaz Blunderflame - 3027, -- Naal Mistrunner - 10667, -- Chromie - 3497, -- Kilxx - 3334, -- Rekkul - 844, -- Antonio Perelli - 1303, -- Felicia Gump - 5940, -- Harn Longcast - 12783, -- Lieutenant Karter - 2381, -- Micha Yance - 16787, -- Argent Outfitter - 5519, -- Billibub Cogspinner - 3960, -- Ulthaan - 15293, -- Aendel Windspear - 12793, -- Brave Stonehide - 734, -- Corporal Bluth - 3954, -- Dalria - 3180, -- Dark Iron Entrepreneur - 1684, -- Khara Deepwater - 4217, -- Mathrengyl Bearwalker - 11536, -- Quartermaster Miranda Breechlock - 8665, -- Shylenai - 3413, -- Sovik - 11057, -- Apothecary Dithers - 4981, -- Ben Trias - 6740, -- Innkeeper Allison - 6746, -- Innkeeper Pala - 5753, -- Martha Strain - 12943, -- Werg Thickblade - 14322, -- Stomper Kreeg - 4610, -- Algernon - 3369, -- Gotri - 6735, -- Innkeeper Saelienne - 10618, -- Rivern Frostwind - 6779, -- Smudge Thunderwood - 6777, -- Zan Shivsproket - 1347, -- Alexandra Bolero - 6576, -- Brienna Starglow - 6367, -- Donni Anthania - 4165, -- Elissa Dumas - 7775, -- Gregan Brewspewer - 7854, -- Jangdor Swiftstrider - 3346, -- Kithas - 4879, -- Ogg'marr - 1285, -- Thurman Mullby - 4731, -- Zachariah Post - 5188, -- Garyl - 2698, -- George Candarte - 2265, -- Hillsbrad Apprentice Blacksmith - 6741, -- Innkeeper Norman - 7736, -- Innkeeper Shyria - 5565, -- Jillian Tanner - 1148, -- Nerrist - 2481, -- Bliztik - 2687, -- Gnaz Blunderflame - 11555, -- Gorn One Eye - 4574, -- Lizbeth Cromwell - 8157, -- Logannas - 3550, -- Martine Tramblay - 15179, -- Mishta - 5109, -- Myra Tyrngaarde - 10118, -- Nessa Shadowsong - 4553, -- Ronald Burch - 2819, -- Tunkk - 5611, -- Barkeep Morag - 6328, -- Dannie Fizzwizzle - 1286, -- Edna Mullby - 4181, -- Fyrenna - 1247, -- Innkeeper Belm - 6790, -- Innkeeper Trelayne - 4305, -- Kriggon Talsone - 4190, -- Kyndri - 3134, -- Kzixx - 4200, -- Laird - 11874, -- Masat T'andr - 4241, -- Mydrannul - 4581, -- Salazar Bloch - 1261, -- Veron Amberstill - 3081, -- Wunna Darkmane - 1682, -- Yanni Stoutheart - 3405, -- Zeal'aya - 989, -- Banalash - 1302, -- Bernard Gump - 3578, -- Dalaran Miner - 5140, -- Edris Barleybeard - 14860, -- Flik - 6739, -- Innkeeper Bates - 8678, -- Jubie Gadgetspring - 9636, -- Kireena - 5758, -- Leo Sarn - 9676, -- Tink Sprocketwhistle - 4226, -- Ulthir - 7952, -- Zjolnir - 465, -- Barkeep Dobbins - 3364, -- Borya - 5101, -- Bryllia Ironbrand - 3096, -- Captured Servant of Azora - 11038, -- Caretaker Alen - 4167, -- Dendrythis - 2812, -- Drovnar Strongbrew - 4891, -- Dwane Wertle - 1328, -- Elly Langston - 3495, -- Gagsprocket - 3547, -- Hamlin Atkins - 15165, -- Haughty Modiste - 11187, -- Himmik - 295, -- Innkeeper Farley - 6734, -- Innkeeper Hearthstove - 1301, -- Julia Gallina - 372, -- Karm Ironquill - 8362, -- Kuruk - 9099, -- Sraaz - 5189, -- Thrumn - 14522, -- Ur'dan - 1685, -- Xandar Goodbeard - 14637, -- Zorbin Fandazzle - 9087, -- Bashana Runetotem - 7978, -- Bimble Longberry - 2838, -- Crazk Sparks - 12021, -- Daeolyn Summerleaf - 3577, -- Dalaran Brewmaster - 233, -- Farmer Saldean - 3367, -- Felika - 5100, -- Fillius Fizzlespinner - 5112, -- Gwenna Firebrew - 3685, -- Harb Clawhoof - 7733, -- Innkeeper Fizzgrimble - 11103, -- Innkeeper Lyshaerya - 12941, -- Jase Farlane - 8121, -- Jaxxil Sparks - 5783, -- Kalldan Felmoon - 1456, -- Kersok Prond - 5848, -- Malgin Barleybrew - 2626, -- Old Man Heming - 12796, -- Raider Bork - 13432, -- Seersa Copperpinch - 15199, -- Sergeant Hartman - 5178, -- Soolie Berryfizz - 14845, -- Stamp Thunderhorn - 14844, -- Sylannia - 3187, -- Tai'tasi - 3366, -- Tamar - 3313, -- Trak'gen - 1678, -- Vernon Hale - 1316, -- Adair Gilroy - 2816, -- Androd Fadran - 11287, -- Baker Masterson - 274, -- Barkeep Hann - 4168, -- Elynna - 3881, -- Grimtak - 15350, -- Horde Warbringer - 11116, -- Innkeeper Abeqwa - 3934, -- Innkeeper Boorand Plainswind - 8150, -- Janet Hommers - 15012, -- Javnir Nashak - 8403, -- Jeremiah Payson - 1318, -- Jessara Cordell - 16256, -- Jessica Chambers - 4589, -- Joseph Moore - 14740, -- Katoom the Angler - 3005, -- Mahu - 5190, -- Merill Pleasance - 4571, -- Morley Bates - 2364, -- Neema - 13018, -- Nipsy - 2832, -- Nixxrax Fillamug - 5193, -- Rebecca Laughlin - 277, -- Roberto Pupellyverbos - 7945, -- Savanne - 4192, -- Taldan - 3016, -- Tand - 1460, -- Unger Statforth - 2118, -- Abigail Shiel - 5173, -- Alexander Calder - 1321, -- Alyssa Griffith - 12384, -- Augustus the Touched - 12957, -- Blimo Gadgetspring - 5128, -- Bombus Finespindle - 2393, -- Christoph Jeffcoat - 6374, -- Cylina Darkheart - 12019, -- Dargon - 2140, -- Edwin Harly - 14481, -- Emmithue Smails - 5483, -- Erika Tate - 3090, -- Gerald Crawley - 12958, -- Gigget Zipcoil - 6731, -- Harlown Darkweave - 4307, -- Heldan Galesong - 2264, -- Hillsbrad Tailor - 6736, -- Innkeeper Keldamyr - 11106, -- Innkeeper Sikewa - 384, -- Katie Hunter - 5748, -- Killian Sanatha - 3937, -- Kira Songshine - 8305, -- Kixxle - 15471, -- Lieutenant General Andorov - 5757, -- Lilly - 3961, -- Maliynn - 2357, -- Merideth Carlson - 12959, -- Nergal - 8178, -- Nina Lightbrew - 13420, -- Penney Copperpinch - 8177, -- Rartar - 982, -- Thultash - 5169, -- Tynnus Venomsprout - 4194, -- Ullanna - 15011, -- Wagner Hammerstrike - 5942, -- Zansoa - 829, -- Adlin Pridedrift - 6496, -- Brivelthwerp - 5514, -- Brooke Stonebraid - 2672, -- Cowardly Crosby - 4894, -- Craig Nollward - 6373, -- Dane Winslow - 1304, -- Darian Singh - 15197, -- Darkcaller Yanka - 7940, -- Darnall - 1453, -- Dewin Shimmerdawn - 4587, -- Elizabeth Van Talen - 3168, -- Flakk - 2682, -- Fradd Swiftgear - 3003, -- Fyr Mistrunner - 3085, -- Gloria Femmel - 4885, -- Gregor MacVince - 3133, -- Herble Baubbletump - 8931, -- Innkeeper Heather - 1464, -- Innkeeper Helbrek - 2388, -- Innkeeper Shay - 7744, -- Innkeeper Thulfram - 1325, -- Jasper Fel - 3884, -- Jhawna Oatwind - 5698, -- Joanna Whitehall - 6382, -- Jubahl Corpseseeker - 7772, -- Kalin Windflight - 790, -- Karen Taylor - 3958, -- Lardan - 2383, -- Lindea Rabonne - 1672, -- Lohgan Eva - 5049, -- Lyesa Steelbrow - 7955, -- Milli Featherwhistle - 7879, -- Quintis Jonespyre - 3499, -- Ranik - 1457, -- Samor Festivus - 8363, -- Shadi Mistrunner - 5191, -- Shalumon - 3333, -- Shankys - 3089, -- Sherman Femmel - 2622, -- Sly Garrett - 8307, -- Tarban Hearthgrain - 15124, -- Targot Jinglepocket - 3935, -- Toddrick - 4782, -- Truk Wildbeard - 4875, -- Turhaw - 1149, -- Uthok - 15864, -- Valadar Starsong - 13433, -- Wulmort Jinglepocket - 3882, -- Zlagk - 7683, -- Alessandro Luca - 777, -- Amy Davenport - 8158, -- Bronk - 5570, -- Bruuk Barleybeard - 8934, -- Christopher Hewen - 1250, -- Drake Lindgren - 4170, -- Ellandrieth - 14963, -- Gapp Jinglepocket - 6567, -- Ghok'kah - 6301, -- Gorbold Steelhand - 14437, -- Gorzeeki Wildeyes - 13436, -- Guchie Jinglepocket - 3956, -- Harklan Moongrove - 894, -- Homer Stonefield - 5111, -- Innkeeper Firebrew - 6747, -- Innkeeper Kauth - 1305, -- Jarel Moor - 13430, -- Jaycrue Copperpinch - 6730, -- Jinky Twizzlefixxit - 2115, -- Joshua Kien - 4615, -- Katrina Alliestar - 13418, -- Kaymard Copperpinch - 1237, -- Kazan Mogosh - 5815, -- Kurgul - 227, -- Mabel Solaj - 13434, -- Macey Jinglepocket - 1313, -- Maria Lumere - 3480, -- Moorane Hearthgrain - 2134, -- Mrs. Winters - 12026, -- My'lanna - 2683, -- Namdo Bizzfizzle - 2380, -- Nandar Branson - 2814, -- Narj Deepslice - 3012, -- Nata Dawnstrider - 8160, -- Nioma - 4265, -- Nyoma - 14450, -- Orphan Matron Nightingale - 8681, -- Outfitter Eric - 2699, -- Rikqiz - 2684, -- Rizz Loosebolt - 2688, -- Ruppo Zipcoil - 4225, -- Saenorion - 3548, -- Selina Weston - 12794, -- Stone Guard Zarg - 5135, -- Svalbrad Farmountain - 3779, -- Syurana - 3518, -- Thomas Miller - 8117, -- Wizbang Booms - 2670, -- Xizk Goodstitch - 12956, -- Zannok Hidepiercer - 14480, -- Alowicious Czervik - 3350, -- Asoran - 2366, -- Barkeep Kelly - 5620, -- Bartender Wental - 2846, -- Blixrez Goodstitch - 3368, -- Borstan - 4255, -- Brogus Thunderbrew - 152, -- Brother Danil - 4084, -- Chylina - 4182, -- Dalmond - 6091, -- Dellylah - 3158, -- Duokna - 5503, -- Eldraeith - 4555, -- Eleanor Rusk - 5160, -- Emrul Riknussun - 4775, -- Felicia Doan - 12795, -- First Sergeant Hola'mahi - 5569, -- Fizzlebang Booms - 4223, -- Fyldan - 3298, -- Gabrielle Chase - 16543, -- Garon Hutchins - 843, -- Gina MacGregor - 4256, -- Golnir Bouldertoe - 1692, -- Golorn Frostbeard - 3358, -- Gorina - 2908, -- Grawl - 8508, -- Gretta Ganter - 5138, -- Gwina Stonebranch - 3540, -- Hal McAllister - 3962, -- Haljan Oakheart - 8152, -- Harnor - 6727, -- Innkeeper Brianna - 7714, -- Innkeeper Byula - 6272, -- Innkeeper Janene - 6930, -- Innkeeper Karakul - 12196, -- Innkeeper Kaylisk - 6738, -- Innkeeper Kimlya - 5688, -- Innkeeper Renee - 9356, -- Innkeeper Shul'kar - 5814, -- Innkeeper Thulbek - 11118, -- Innkeeper Vizzie - 3544, -- Jason Lemieux - 4876, -- Jawn Highmesa - 3498, -- Jazzik - 4590, -- Jonathan Chambers - 258, -- Joshua Maclure - 6574, -- Jun'ha - 15353, -- Katrina Shimmerstar - 1697, -- Keeg Gibn - 3348, -- Kor'geld - 3329, -- Kor'jus - 5870, -- Krond - 1671, -- Lamar Veisilli - 5871, -- Larhka - 4730, -- Lelanai - 8118, -- Lillian Singh - 791, -- Lindsay Ashlock - 1694, -- Loslor Rudge - 15898, -- Lunar Festival Vendor - 3587, -- Lyrai - 2303, -- Lyranne Feathersong - 2394, -- Mallen Swain - 3010, -- Mani Winterhoof - 7941, -- Mardrack Greenwell - 1670, -- Mike Miller - 13429, -- Nardstrum Copperpinch - 7485, -- Nargatt - 3614, -- Narret Shadowgrove - 3014, -- Nida Winterhoof - 14738, -- Otho Moji'ko - 5132, -- Pithwick - 5154, -- Poranna Snowbraid - 15354, -- Rachelle Gothena - 3541, -- Sarah Raycroft - 955, -- Sergeant De Vries - 3029, -- Sewa Mistrunner - 3342, -- Shan'ti - 2669, -- Sheri Zipstitch - 5124, -- Sognar Cliffbeard - 4221, -- Talaelar - 1650, -- Terry Palin - 4617, -- Thaddeus Webb - 5158, -- Tilli Thistlefuzz - 4195, -- Tiyani - 4899, -- Uma Bartulm - 4954, -- Uttnar - 4189, -- Valdaron - 4222, -- Voloren - 13431, -- Whulwert Copperpinch - 2842, -- Wigcik - 8404, -- Xan'tish - 4230, -- Yldan - 8116, -- Ziggle Sparks - 2225, -- Zora Guthrek - 3608, -- Aldia - 4191, -- Allyndia - 3481, -- Barg - 4893, -- Bartender Lillian - 151, -- Brog Hamfist - 2365, -- Bront Coldcleave - 5163, -- Burbik Gearspanner - 4216, -- Chardryn - 4896, -- Charity Mipsy - 12960, -- Christi Galvanis - 2697, -- Clyde Ranthal - 2668, -- Danielle Zipstitch - 4266, -- Danlyia - 3411, -- Denni'ka - 2397, -- Derak Nightfall - 15006, -- Deze Snowbane - 14962, -- Dillord Copperpinch - 3969, -- Fahran Silentblade - 7942, -- Faralorn - 3091, -- Franklin Hamar - 3705, -- Gahroot - 5750, -- Gina Lang - 2820, -- Graud - 4082, -- Grawnal - 3291, -- Greishan Ironstove - 12807, -- Greshka - 3086, -- Gretchen Vogel - 1452, -- Gruham Rumdnul - 3708, -- Gruna - 10216, -- Gubber Blump - 960, -- Gunder Thornbush - 5886, -- Gwyn Farrow - 3933, -- Hai'zan - 7943, -- Harklane - 14964, -- Hecht Copperpinch - 3948, -- Honni Goldenoat - 12776, -- Hraug - 9501, -- Innkeeper Adegwa - 2352, -- Innkeeper Anderson - 16458, -- Innkeeper Faralia - 7737, -- Innkeeper Greul - 6928, -- Innkeeper Grosk - 6929, -- Innkeeper Gryshka - 7731, -- Innkeeper Jayka - 6737, -- Innkeeper Shaussiy - 6807, -- Innkeeper Skindle - 6791, -- Innkeeper Wiley - 4169, -- Jaeana - 3164, -- Jark - 1311, -- Joachim Brenlow - 5134, -- Jonivera Farmountain - 3186, -- K'waii - 3025, -- Kaga Mistrunner - 3487, -- Kalyimah Stormcloud - 3072, -- Kawnie Softbreeze - 5749, -- Kayla Smithe - 2401, -- Kayren Soothallow - 13435, -- Khole Jinglepocket - 6027, -- Kitha - 8122, -- Kizzak Sparks - 15125, -- Kosco Copperpinch - 1691, -- Kreg Bilmn - 3621, -- Kurll - 3002, -- Kurm Stonehoof - 3561, -- Kyrai - 3689, -- Laer Stepperunner - 12028, -- Lah'Mawhani - 14731, -- Lard - 8143, -- Loorana - 11186, -- Lunnix Sprocketslip - 12031, -- Mai'Lahii - 3135, -- Malissa - 3044, -- Miles Welsh - 4577, -- Millie Gregorian - 14961, -- Mirvyna Jinglepocket - 3883, -- Moodan Sungrain - 3076, -- Moorat Longstride - 3017, -- Nan Mistrunner - 3959, -- Nantar - 2084, -- Natheril Raincaller - 3312, -- Olvia - 8364, -- Pakwa - 3551, -- Patrice Dwyer - 491, -- Quartermaster Lewis - 1474, -- Rann Flamespinner - 3625, -- Rarck - 6495, -- Riznek - 4599, -- Sarah Killian - 3138, -- Scott Carevin - 10367, -- Shrye Ragefist - 5520, -- Spackle Thornberry - 3178, -- Stuart Fleming - 4554, -- Tawny Grisette - 6298, -- Thelgrum Stonehammer - 12027, -- Tukk - 4228, -- Vaean - 2808, -- Vikki Lonsav - 6568, -- Vizzklick - 12962, -- Wik'Tar - 3485, -- Wrahk - 6376, -- Wren Darkspring - 3400, -- Xen'to - 5944, -- Yonada - 3572, -- Zizzek - 18960, -- Rungor - 18484, -- Wind Trader Lathrai - 18911, -- Juno Dufrain - 18756, -- Haris Pilton - 19663, -- Madame Ruby - 19186, -- Kylene - 27721, -- Drelik Blastpipe - 19213, -- Eiin - 27722, -- Drolig Blastpipe - 18753, -- Felannia - 20097, -- Nula the Butcher - 20028, -- Doba - 18015, -- Gambarinka - 21655, -- Nakodu - 20096, -- Uriku - 19837, -- Daga Ramba - 23604, -- Agnes Farwithers - 20080, -- Galgrom - 18751, -- Kalaen - 27668, -- Ontok Shatterhorn - 19321, -- Quartermaster Endarin - 21643, -- Alurmi - 16585, -- Cookie One-Eye - 18773, -- Johan Barnes - 16826, -- Sid Limbardi - 18005, -- Haalrun - 19227, -- Griftah - 18525, -- G'eras - 18774, -- Tatiana - 18775, -- Lebowski - 16782, -- Yatheon - 21432, -- Almaador - 16602, -- Floyd Pinkus - 19296, -- Innkeeper Biribi - 19331, -- Quartermaster Enuril - 17585, -- Quartermaster Urgronn - 18988, -- Baxter - 19196, -- Cro Threadstrong - 17657, -- Logistics Officer Ulrike - 19661, -- Viggz Shinesparked - 18898, -- Explodyne Fizzlespurt - 20807, -- Scribe Saalyn - 19042, -- Leeli Longhaggle - 16689, -- Zaralda - 18987, -- Gaston - 16657, -- Feera - 20808, -- Scribe Veredis - 25976, -- Theremis - 18990, -- Burko - 20981, -- Dealer Najeeb - 16860, -- Jilanne - 16635, -- Lyna - 16253, -- Master Chef Mouldier - 17584, -- Torallius the Pack Handler - 25178, -- Ecton Brasstumbler - 18957, -- Innkeeper Grilka - 19074, -- Skreah - 20278, -- Vixton Pinchwhistle - 18266, -- Warrant Officer Tracy Proudwell - 18991, -- Aresella - 20986, -- Dealer Tariq - 23489, -- Drake Dealer Hurlunk - 25032, -- Eldara Dawnrunner - 19772, -- Spirit Sage Gartok - 20916, -- Xerintha Ravenoak - 18255, -- Apprentice Darius - 16641, -- Melaris - 22212, -- Andrion Darkspinner - 16262, -- Landraelanis - 19038, -- Supply Officer Mills - 20980, -- Dealer Rashaad - 16722, -- Egomis - 19773, -- Spirit Sage Zran - 16367, -- Botanist Tyniarrel - 18906, -- Caregiver Ophera Windfury - 19053, -- Fabian Lanzonelli - 18907, -- Innkeeper Coryth Stoktron - 18993, -- Naka - 22208, -- Nasmara Moonsong - 20989, -- Dealer Sadaqat - 16224, -- Rathis Tomber - 24934, -- Snack-O-Matic IV - 27817, -- Brew Vendor - 18771, -- Brumman - 20494, -- Dama Wildmane - 24408, -- Gunter - 23484, -- Haldor the Compulsive - 19065, -- Inessera - 23521, -- Anne Summers - 18267, -- Battlecryer Blackeye - 26352, -- Big Zokk Torquewrench - 18772, -- Hama - 18564, -- Horde Field Scout - 19182, -- Shaarubo - 18897, -- "King" Dond - 23245, -- Aether-tech Master - 19617, -- Boots - 17421, -- Clopper Wizbang - 19857, -- Meminnie - 26092, -- Soryn - 19245, -- Vinemaster Alamaro - 18018, -- Zurjaya - 18542, -- Alexston Chrome - 19521, -- Arrond - 18754, -- Barim Spilthoof - 23263, -- Brendan Turner - 19534, -- Dealer Digriz - 17101, -- Diktynna - 18427, -- Fazu - 16766, -- Issca - 22270, -- Ogri'la Merchant - 22271, -- Ogri'la Trader - 21019, -- Sixx - 18752, -- Zebig - 17246, -- "Cookie" McWeaksauce - 19017, -- Borto - 18914, -- Caregiver Isel - 16709, -- Cuzi - 18749, -- Dalinna - 19197, -- Eral - 25179, -- Frixee Brasstumbler - 24993, -- Galley Chief Mariss - 19050, -- Garul - 16444, -- Halis Dawnstrider - 18929, -- Kyrenna - 15397, -- Marniel Amberlight - 27666, -- Ontuvo - 18821, -- Quartermaster Jaffrey Noreliqe - 18947, -- Solanin - 19244, -- Trader Endernor - 25034, -- Tradesman Portanuus - 16264, -- Winaestra - 21488, -- Banro - 21111, -- Bembil Knockhammer - 20510, -- Brunn Flamebeard - 18251, -- Caregiver Abidaar - 16267, -- Daestra - 18959, -- Dod'ss - 24510, -- Driz Tumblequick - 16268, -- Eralan - 16624, -- Gelanthis - 22213, -- Gidge Spellweaver - 23437, -- Indormi - 18908, -- Innkeeper Kerp - 23428, -- Jho'nass - 26124, -- Midsummer Merchant - 16768, -- Nurguni - 20241, -- Provisioner Nasela - 21113, -- Sassa Weldwell - 23606, -- Suntouched Apprentice - 25977, -- Yrma - 19234, -- Yurial Soulwater - 17512, -- Arred - 19540, -- Asarnan - 24495, -- Blix Fixwidget - 27814, -- Brew Vendor - 27818, -- Brew Vendor - 23605, -- Bron - 16739, -- Caregiver Breel - 25176, -- Grikkin Copperspring - 19232, -- Innkeeper Haelthol - 19195, -- Jim Saltit - 19345, -- Kalara - 19474, -- Karnaze - 21906, -- Kelara - 23699, -- Kevin Browning - 24392, -- Leeni "Smiley" Smalls - 25195, -- Marksman Bova - 19015, -- Mathar G'ochar - 26123, -- Midsummer Supplier - 16767, -- Neii - 19045, -- Oloraak - 19372, -- Oran Blusterbrew - 21744, -- Roldemar - 23510, -- Thunderbrew Apprentice - 20240, -- Trader Narasu - 21905, -- Veynna Dawnstar - 16442, -- Vinemaster Suntouched - 15494, -- Yasmine Teli'Larien - 24208, -- "Little" Logok - 18664, -- Aged Dalaran Wizard - 19932, -- Andormu - 20249, -- Cymbre Starsong - 16708, -- Dekin - 19495, -- Innkeeper Shaunessy - 26089, -- Kayri - 23396, -- Krixel Pinchwhistle - 27478, -- Larkin Thunderbrew - 26395, -- Lieutenant Tristia - 24975, -- Mar'nah - 16613, -- Parnis - 19562, -- Peon Bolgar - 16718, -- Phea - 24468, -- Pol Amberstill - 16187, -- Quartermaster Lymel - 27489, -- Ray'ma - 23363, -- Sahaak - 16649, -- Torian - 16443, -- Zalene Firstlight - 23244, -- Aether-tech Adept - 23243, -- Aether-tech Assistant - 23483, -- Arcanist Xorith - 23522, -- Arlen Lochlan - 17222, -- Artificer Daelo - 19371, -- Dalin Stouthammer - 16683, -- Darlia - 19538, -- Dealer Senzik - 25177, -- Evee Copperspring - 21110, -- Fizit "Doc" Clocktock - 17630, -- Innkeeper Jovia - 16618, -- Innkeeper Velandra - 19539, -- Jazdalaad - 23748, -- Kurzel - 21145, -- Little Azimi - 23535, -- Matero Zeshuwal - 19664, -- Muffin Man Moser - 22266, -- Ogri'la Grubgiver - 18810, -- Otonambusi - 19450, -- Pol Snowhoof - 17277, -- Provisioner Valine - 15287, -- Shara Sunwing - 23010, -- Wolgren Jinglepocket - 23896, -- "Dirty" Michael Crowe - 18581, -- Alliance Field Scout - 23995, -- Axle - 20377, -- Barkeep Kelly - 23482, -- Barleybrew Apprentice - 23710, -- Belbi Quikswitch - 16650, -- Bithrus - 27810, -- Brew Vendor - 27820, -- Brew Vendor - 27806, -- Brew Vendor - 25036, -- Caregiver Inaara - 21487, -- Cendrii - 20378, -- Chef Jessen - 19435, -- Dark Cleric Malod - 19537, -- Dealer Malij - 16638, -- Deynna - 19649, -- Dorni - 19352, -- Dreg Cloudsweeper - 24501, -- Drohn's Distillery Apprentice - 23064, -- Eebee Jinglepocket - 21484, -- Embelar - 17490, -- Ergh of the Stillpine - 21083, -- Erool - 19531, -- Eyonix - 19518, -- Feranin - 25012, -- Galley Chief Gathers - 24834, -- Galley Chief Grace - 25089, -- Galley Chief Steelbelly - 19572, -- Gant - 19470, -- Gholah - 19223, -- Granny Smith - 28225, -- Griz Gutshank - 16748, -- Haferet - 18905, -- Innkeeper Bazil Olof'tazun - 16610, -- Kredis - 19330, -- Lisrythe Bloodwatch - 18913, -- Matron Tikkit - 18811, -- Meriaad - 16751, -- Merran - 19559, -- Mondul - 20893, -- Morula - 23110, -- Ogri'la Keg King - 23065, -- Olnayvi Copperpinch - 26091, -- Olus - 16732, -- Onnis - 18009, -- Puluu - 18822, -- Quartermaster Davian Vaclav - 20892, -- Ruogo - 16920, -- Ryosh - 19374, -- Salle Sunforge - 21172, -- Sarinei Whitestar - 16366, -- Sempstress Ambershine - 16259, -- Sheri - 23533, -- T'chali's Voodoo Brewery Apprentice - 19498, -- Tanaide - 21483, -- Tasaldan - 24545, -- Thunderbrew "Apprentice" - 25035, -- Tyrael Flamekissed - 16664, -- Zelan - 19625, -- Alorya - 16705, -- Altaa - 16713, -- Arras - 23009, -- Bessbi Jinglepocket - 21084, -- Braagor - 27816, -- Brew Vendor - 27811, -- Brew Vendor - 27819, -- Brew Vendor - 23525, -- Brother Cartwright - 19497, -- Caoileann - 16553, -- Caregiver Chellan - 17553, -- Caregiver Topher Loaal - 21746, -- Caretaker Aluuro - 19573, -- Dash - 19533, -- Dealer Aljaan - 20194, -- Dealer Dunar - 19532, -- Dearny - 18951, -- Erilia - 19194, -- Ernie Packwell - 20121, -- Fingin - 25020, -- Galley Chief Alunwea - 25052, -- Galley Chief Halumvorea - 23511, -- Gordok Brew Apprentice - 17656, -- Heron Skygaze - 23143, -- Horus - 15433, -- Innkeeper Delaniel - 16542, -- Innkeeper Kalarin - 19049, -- Karokka - 26090, -- Karynna - 23481, -- Keiran Donoghue - 18277, -- Kinamisa - 19574, -- Kizzie - 23573, -- Krixil Slogswitch - 21082, -- Krugash - 17489, -- Logan Daniel - 19560, -- Lukra - 19020, -- Matron Qualia - 18245, -- Merajit - 19836, -- Mixie Farshot - 19722, -- Muheru the Weaver - 19243, -- Nalama the Merchant - 19021, -- Nancila - 19528, -- Nanomah - 19471, -- Old Orok - 18347, -- Olirea - 17446, -- Parkat Steelfur - 16798, -- Provisioner Anir - 19451, -- Quartermaster Gorman - 16677, -- Quelis - 21085, -- Ragar - 20250, -- Rashere Pridehoof - 16690, -- Rathin - 18954, -- Sailor Melinan - 16191, -- Sathren Azuredawn - 25043, -- Sereth Duskbringer - 25950, -- Shaani - 20891, -- Skraa - 23208, -- Skyguard Pyrotechnician - 19348, -- Targrom - 19472, -- Threlc - 19343, -- Trop Rendlimb - 23603, -- Uta Roughdough - 17486, -- Ziz - 32538, -- Duchess Mynx - 32216, -- Mei Francis - 30431, -- Veteran Crusader Aliocha Segard - 32540, -- Lillehoff - 199387, -- D3-BA - 31247, -- Roxi Ramrocket - 31238, -- Hira Snowdawn - 32287, -- Archmage Alvareaux - 32533, -- Cielstrasza - 32763, -- Sairuk - 34885, -- Dame Evniki Kapsalis - 31916, -- Tanaika - 28715, -- Endora Moorehead - 32296, -- Stone Guard Mukar - 40160, -- Frozo the Renowned - 32565, -- Gara Skullcrush - 32172, -- Harold Winston - 32294, -- Knight Dameron - 32564, -- Logistics Officer Silverstone - 211332, -- Korralin Hoperender - 211340, -- Kolara Dreamsmasher - 28742, -- Marcia Chase - 207128, -- Animated Constellation - 33557, -- Trellis Morningsun - 31580, -- Arcanist Ivrenne - 33555, -- Eliza Killian - 31910, -- Geen - 29587, -- Dread Commander Thalanor - 32774, -- Sebastian Crane - 35494, -- Arcanist Miluria - 31582, -- Magistrix Lambriesse - 35826, -- Kaye Toogie - 28701, -- Timothy Jones - 33634, -- Engineer Sinbei - 33653, -- Rook Hawkfist - 32515, -- Braeg Stoutbeard - 33682, -- Fono - 33963, -- Magister Sarien - 32773, -- Logistics Officer Brighton - 33553, -- Freka Bloodaxe - 32509, -- Brammold Deepmine - 32514, -- Vanessa Sellers - 33640, -- Hanlir - 33554, -- Samamba - 35508, -- Enchanter Erodin - 35507, -- Enchanter Isian - 33307, -- Corporal Arthur Flew - 33650, -- Rillie Spindlenut - 30730, -- Stanly McCormick - 33310, -- Derrick Brindlebeard - 33657, -- Irisee - 35577, -- Valiant Laradia - 33026, -- Sarah Brady - 29535, -- Alchemist Cinesra - 29744, -- Rork Sharpchin - 35578, -- Valiant Bressia - 37941, -- Magister Arlan - 31031, -- Misensi - 31032, -- Derek Odds - 34772, -- Vasarin Redmorn - 29493, -- Jarold Puller - 32380, -- Lieutenant Tristia - 37942, -- Arcanist Uovril - 32836, -- Noblegarden Vendor - 28776, -- Elizabeth Ross - 27760, -- "Grizzly" D. Adams - 31581, -- Magister Brasael - 30472, -- Olut Alegut - 28721, -- Tiffany Cartier - 28687, -- Amisi Azuregaze - 29478, -- Jepetto Joybuzz - 31579, -- Arcanist Adurin - 28951, -- Breanni - 30723, -- Xantili - 32382, -- Lady Palanseer - 27730, -- Purkom - 33556, -- Doru Thunderhorn - 33636, -- Miralisse - 32837, -- Noblegarden Merchant - 29547, -- Applebough - 30885, -- Blazik Fireclaw - 28726, -- Dominique Stefano - 32413, -- Isirami Fairwind - 29628, -- Angelique Butler - 35580, -- Aspirant Naradiel - 26110, -- Librarian Serrah - 35575, -- Champion Isimode - 35495, -- Magistrix Vesara - 33595, -- Mera Mistrunner - 26977, -- Adelene Sunlance - 34881, -- Hiren Loresong - 32354, -- Leeni "Smiley" Smalls - 37674, -- Lovely Merchant - 29532, -- Ajay Green - 29491, -- Karandonna - 28993, -- Aerith Primrose - 35099, -- Bana Wildmane - 32337, -- Christi Stockton - 32362, -- Evee Copperspring - 33027, -- Jessica Sellers - 33964, -- Arcanist Firael - 26484, -- Hugh Glass - 33679, -- Recorder Lidio - 31911, -- Tanak - 33677, -- Technician Mihila - 33996, -- William Saldean - 31557, -- Uda the Beast - 33631, -- Barien - 35576, -- Champion Faesrol - 26938, -- Groll - 33638, -- Scribe Lanloer - 33684, -- Weaver Aoa - 24539, -- "Silvermoon" Harry - 29716, -- Clockwork Assistant - 33853, -- Broxel Goldgrasp - 29715, -- Fialla Sweetberry - 28347, -- Miles Sidney - 29495, -- Norvin Alderman - 39173, -- Champion Ros'slai - 28692, -- "Red" Jack Findle - 32355, -- Big Zokk Torquewrench - 32379, -- Captain O'Neal - 29528, -- Debbi Moore - 33678, -- Jijia - 26995, -- Tink Brightbolt - 25248, -- "Salty" John Thorpe - 35574, -- Magistrix Iruvia - 29527, -- Orton Bennet - 24291, -- Anton - 33637, -- Kirembri Silvermane - 34682, -- Wilmina Holbeck - 33596, -- Meline Duskpath - 28718, -- Ranid Glowergold - 29122, -- Rarkag - 29548, -- Aimee - 32359, -- Argex Irongut - 35579, -- Aspirant Forudir - 35131, -- Durgan Thunderbeak - 26959, -- Booker Kells - 26718, -- Trader Alorn - 30488, -- Travis Day - 32356, -- Kezzik the Striker - 28723, -- Larana Drome - 29529, -- Ninsianna - 26868, -- Provisioner Lorkran - 34382, -- Chapman - 29277, -- Datalore Smallsphere - 32415, -- Hamaka - 32642, -- Mojodishu - 33680, -- Nemiha - 33675, -- Onodo - 30011, -- Sigdis the Trader - 27193, -- Alornerk - 33602, -- Anuur - 29702, -- Chameli Banaphash - 35101, -- Grunda Bronzewing - 28868, -- Mulch - 35573, -- Arcanist Asarina - 29208, -- Fester - 31101, -- Hoodoo Master Fu'jin - 34683, -- Rose Standish - 28691, -- Susana Averoy - 24342, -- Timothy Holland - 29270, -- Aspen Grove Trader - 24054, -- Balar Rumsbane - 194795, -- Fishspeaker Irtusk - 28046, -- Korg the Cleaver - 39172, -- Marshal Magruder - 32420, -- Mimbihi - 26916, -- Mindri Dinkles - 27144, -- Noatak - 28792, -- Noggra - 29261, -- Windle Sparkshine - 32631, -- Alfred Copperworth - 29275, -- Aspen Grove Supplier - 24341, -- Barnabas Frye - 33639, -- Botanist Alaenra - 35343, -- Bountiful Barrel - 35341, -- Bountiful Barrel - 26941, -- Brokkan Bear-Arms - 29207, -- Gangrenus - 32638, -- Hakmud of Argus - 34681, -- Ikaneba Summerset - 30735, -- Kul Inkspiller - 30724, -- Mertle Murkpen - 27938, -- Trizormu - 25278, -- Williamson - 30098, -- Amphitheater Vendor - 35342, -- Bountiful Barrel - 34685, -- Dalni Tallgrass - 29291, -- Galley Chief Paul Kubit - 29905, -- Grillix Bonesaw - 28589, -- Gristlegut - 30254, -- Marisalira - 30489, -- Morgan Day - 29908, -- Plip Fatpurse - 28038, -- Purser Boulian - 27022, -- Afha - 28707, -- Angelo Pescatore - 29049, -- Arille Azuregaze - 35337, -- Bountiful Barrel - 199649, -- Crafted Gearataur - 32360, -- Ecton Brasstumbler - 27142, -- Librarian Jeffers - 33597, -- Liere Morningsong - 26709, -- Pahu Frosthoof - 29583, -- Pan'ya - 29703, -- Sheddle Glossgleam - 31051, -- Sorceress Kaylana - 27146, -- Uukkarnit - 29512, -- Ainderu Summerleaf - 27031, -- Apothecary Rose - 27187, -- Caregiver Poallu - 24057, -- Christina Daniels - 28869, -- Deathdrip - 30729, -- Ickabod Pimlen - 30731, -- Illianna Moonscribe - 23937, -- Innkeeper Celeste Goodhutch - 29121, -- Soo-yum - 31021, -- Sophie Aaren - 27145, -- Tipvigut - 35132, -- Tohfo Skyhoof - 32419, -- Umbiwa - 28994, -- Abra Cadabra - 26680, -- Aiyan Coldwind - 33866, -- Akrittok - 27125, -- Barracks Master Rhekku - 30306, -- Bileblow - 35338, -- Bountiful Barrel - 27174, -- Caregiver Mumik - 28798, -- Claudia Bloodraven - 29205, -- Corpulous - 28682, -- Inzi Charmlight - 29244, -- Jesse Masters - 33681, -- Korim - 26939, -- Koro the Wanderer - 30727, -- Lelorian - 27940, -- Lethecus - 27147, -- Librarian Erickson - 27070, -- Lisa Philbrook - 28685, -- Narisa Redgold - 28725, -- Patricia Egan - 27182, -- Takubvik - 27195, -- Tarralikitak - 27063, -- Vrok - 29971, -- Wabada Whiteflower - 26945, -- Zend'li Venomtusk - 26596, -- "Charlie" Northtop - 27148, -- Caregiver Iqniq - 26936, -- Chaska Frosthoof - 33635, -- Daenril - 28727, -- Edward Egan - 24053, -- Helga Rumsbane - 29962, -- Horgoru the Collector - 23731, -- Innkeeper Hazel Lagras - 25245, -- James Deacon - 34684, -- Laha Farplain - 29510, -- Linna Bruder - 30005, -- Lodge-Matron Embla - 29963, -- Magorn - 33865, -- Makuli - 31017, -- Mal Corricks - 30311, -- Mangled - 32421, -- Marcella Bloom - 33019, -- Megan Owings - 27181, -- Qannik - 27132, -- Sani'i - 30256, -- Scout Ordimbral - 30257, -- Scout Yribria - 29904, -- Smilin' Slirk Brassknob - 28867, -- Spiked - 28872, -- Squirmworm - 24147, -- Tara Cooper - 33872, -- Torgah - 27021, -- Tradesman Kontor - 26567, -- Aegalas - 28828, -- Ansari - 24333, -- Bartender Jason Goodhutch - 27012, -- Beem Goldsprocket - 27071, -- Benjamin Jacobs - 24033, -- Bori Wintertotem - 35340, -- Bountiful Barrel - 24343, -- Brock Olson - 33600, -- Cerie Larksong - 32426, -- Coira Longrifle - 23737, -- Coot "The Stranger" Albertson - 30437, -- Crusader Marisse - 29970, -- Danho Farcloud - 24148, -- David Marks - 27950, -- Demestrasz - 28728, -- Dorian Fines - 33683, -- Dremm - 27038, -- Drolfy - 33601, -- Elka Stormbrew - 33644, -- Ellia Moondancer - 27041, -- Fanny McLumpkins - 30346, -- Galley Chief Dolinger - 31022, -- George Goodman - 29926, -- Gunda Boldhammer - 27042, -- Illusia Lune - 27184, -- Imnek - 30070, -- Initiate Gahark - 33645, -- Jenna Thunderbrew - 33018, -- Jennifer Owings - 29511, -- Lalla Brightweave - 27053, -- Lanus Longleaf - 28812, -- Lapu Stormhorn - 27143, -- Librarian Ingram - 27032, -- Lovely Liddia - 29714, -- Lucian Trias - 26374, -- Maevin Farmoon - 27052, -- Naohain - 32334, -- Nixi Fireclaw - 29944, -- Peon Gakra - 26375, -- Quartermaster McCarty - 28830, -- Ra'wiri - 27026, -- Rohesia Werner - 32403, -- Sandra Bartan - 27057, -- Saramer Whitewillow - 28829, -- Saree - 30732, -- Sessoh - 30309, -- Shambles - 30439, -- Sister Colleen Tulley - 32416, -- Stefen Cotter - 24141, -- Stephen Barone - 30733, -- Thargen Heavyquill - 27043, -- Trixy Trixerton - 30827, -- Utamu - 26388, -- Veira Langdon - 23802, -- Wink Sprinklesprankle - 26568, -- Zebu'tan - 28799, -- Alanna - 28807, -- Amarante - 30255, -- Aniduria - 27137, -- Apprentice Fraser - 24149, -- Basil Osgood - 30310, -- Boltskull - 28811, -- Brady Ironcrock - 28806, -- Chad Carter - 28832, -- Chin'ika - 28866, -- Corrosion - 26720, -- Danook Stormwhisper - 27051, -- Doldaen - 34645, -- Elizabeth Barker Winslow - 33598, -- Fanii - 24356, -- Glen Roberts - 27025, -- Harold Haggler - 27066, -- Jennifer Bell - 30734, -- Jezebel Bican - 28794, -- Kevin Weaver - 27058, -- Korag Keeneye - 32424, -- Laire Brewgold - 28810, -- Lessien - 27140, -- Librarian Andersen - 27141, -- Librarian Hamilton - 28791, -- Marissa Everwatch - 32412, -- Mato - 27069, -- Matron Magah - 27027, -- Mrs. Winterby - 27044, -- Ordal McLumpkins - 24348, -- Patrick Hall - 34783, -- Ranisa Whitebough - 29925, -- Rutner Steelpick - 27089, -- Saffron Reynolds - 32478, -- Slosh - 23732, -- Sorely Twitchblade - 31019, -- Stephanie Sindree - 33868, -- Tingiyok - 33869, -- Torngasak - 27190, -- Tupit - 28831, -- Yamuna + [MERCHANT] = { + [5594] = true, -- Alchemist Pestlezugg + [8137] = true, -- Gikkix + [2685] = true, -- Mazk Snipeshot + [14846] = true, -- Lhara + [12022] = true, -- Lorelae Wintersong + [7947] = true, -- Vivianna + [3556] = true, -- Andrew Hilbert + [340] = true, -- Kendor Kabonka + [12919] = true, -- Nat Pagle + [2806] = true, -- Bale + [1465] = true, -- Drac Roughcut + [2664] = true, -- Kelsey Yance + [8145] = true, -- Sheendra Tallgrass + [4561] = true, -- Daniel Bartlett + [8139] = true, -- Jabbey + [1448] = true, -- Neal Allen + [8125] = true, -- Dirge Quikcleave + [4229] = true, -- Mythrin'dir + [66] = true, -- Tharynn Bouden + [2821] = true, -- Keena + [15419] = true, -- Kania + [11056] = true, -- Alchemist Arbington + [5494] = true, -- Catherine Leland + [4877] = true, -- Jandia + [9499] = true, -- Plugger Spazzring + [12944] = true, -- Lokhtos Darkbargainer + [2803] = true, -- Malygen + [3362] = true, -- Ogunaro Wolfrunner + [11189] = true, -- Qia + [8666] = true, -- Lil Timmy + [3482] = true, -- Tari'qa + [7564] = true, -- Marin Noggenfogger + [16786] = true, -- Argent Quartermaster + [12781] = true, -- Master Sergeant Biggins + [2810] = true, -- Hammon Karwn + [12245] = true, -- Vendor-Tron [1000] = true + [3955] = true, -- Shandrina + [12246] = true, -- Super-Seller [680] = true + [3489] = true, -- Zargh + [15174] = true, -- Calandrath + [12043] = true, -- Kulwia + [15351] = true, -- Alliance Brigadier General + [8401] = true, -- Halpa + [6548] = true, -- Magus Tirth + [4585] = true, -- Ezekiel Graves + [1326] = true, -- Sloan McCoy + [5162] = true, -- Tansy Puddlefizz + [12033] = true, -- Wulan + [17598] = true, -- Renn'az + [3546] = true, -- Bernie Heisten + [483] = true, -- Elaine Trias + [11188] = true, -- Evie Whirlbrew + [3443] = true, -- Grub + [14847] = true, -- Professor Thaddeus Paleo + [4453] = true, -- Wizzle Brassbolts + [11185] = true, -- Xizzer Fizzbolt + [1263] = true, -- Yarlyn Amberstill + [5175] = true, -- Gearcutter Cogspinner + [2848] = true, -- Glyx Brewright + [11557] = true, -- Meilosh + [2663] = true, -- Narkk + [5817] = true, -- Shimra + [2480] = true, -- Bro'kin + [4897] = true, -- Helenia Olden + [8679] = true, -- Knaz Blunderflame + [3027] = true, -- Naal Mistrunner + [10667] = true, -- Chromie + [3497] = true, -- Kilxx + [3334] = true, -- Rekkul + [844] = true, -- Antonio Perelli + [1303] = true, -- Felicia Gump + [5940] = true, -- Harn Longcast + [12783] = true, -- Lieutenant Karter + [2381] = true, -- Micha Yance + [16787] = true, -- Argent Outfitter + [5519] = true, -- Billibub Cogspinner + [3960] = true, -- Ulthaan + [15293] = true, -- Aendel Windspear + [12793] = true, -- Brave Stonehide + [734] = true, -- Corporal Bluth + [3954] = true, -- Dalria + [3180] = true, -- Dark Iron Entrepreneur + [1684] = true, -- Khara Deepwater + [4217] = true, -- Mathrengyl Bearwalker + [11536] = true, -- Quartermaster Miranda Breechlock + [8665] = true, -- Shylenai + [3413] = true, -- Sovik + [11057] = true, -- Apothecary Dithers + [4981] = true, -- Ben Trias + [6740] = true, -- Innkeeper Allison + [6746] = true, -- Innkeeper Pala + [5753] = true, -- Martha Strain + [12943] = true, -- Werg Thickblade + [14322] = true, -- Stomper Kreeg + [4610] = true, -- Algernon + [3369] = true, -- Gotri + [6735] = true, -- Innkeeper Saelienne + [10618] = true, -- Rivern Frostwind + [6779] = true, -- Smudge Thunderwood + [6777] = true, -- Zan Shivsproket + [1347] = true, -- Alexandra Bolero + [6576] = true, -- Brienna Starglow + [6367] = true, -- Donni Anthania + [4165] = true, -- Elissa Dumas + [7775] = true, -- Gregan Brewspewer + [7854] = true, -- Jangdor Swiftstrider + [3346] = true, -- Kithas + [4879] = true, -- Ogg'marr + [1285] = true, -- Thurman Mullby + [4731] = true, -- Zachariah Post + [5188] = true, -- Garyl + [2698] = true, -- George Candarte + [2265] = true, -- Hillsbrad Apprentice Blacksmith + [6741] = true, -- Innkeeper Norman + [7736] = true, -- Innkeeper Shyria + [5565] = true, -- Jillian Tanner + [1148] = true, -- Nerrist + [2481] = true, -- Bliztik + [2687] = true, -- Gnaz Blunderflame + [11555] = true, -- Gorn One Eye + [4574] = true, -- Lizbeth Cromwell + [8157] = true, -- Logannas + [3550] = true, -- Martine Tramblay + [15179] = true, -- Mishta + [5109] = true, -- Myra Tyrngaarde + [10118] = true, -- Nessa Shadowsong + [4553] = true, -- Ronald Burch + [2819] = true, -- Tunkk + [5611] = true, -- Barkeep Morag + [6328] = true, -- Dannie Fizzwizzle + [1286] = true, -- Edna Mullby + [4181] = true, -- Fyrenna + [1247] = true, -- Innkeeper Belm + [6790] = true, -- Innkeeper Trelayne + [4305] = true, -- Kriggon Talsone + [4190] = true, -- Kyndri + [3134] = true, -- Kzixx + [4200] = true, -- Laird + [11874] = true, -- Masat T'andr + [4241] = true, -- Mydrannul + [4581] = true, -- Salazar Bloch + [1261] = true, -- Veron Amberstill + [3081] = true, -- Wunna Darkmane + [1682] = true, -- Yanni Stoutheart + [3405] = true, -- Zeal'aya + [989] = true, -- Banalash + [1302] = true, -- Bernard Gump + [3578] = true, -- Dalaran Miner + [5140] = true, -- Edris Barleybeard + [14860] = true, -- Flik + [6739] = true, -- Innkeeper Bates + [8678] = true, -- Jubie Gadgetspring + [9636] = true, -- Kireena + [5758] = true, -- Leo Sarn + [9676] = true, -- Tink Sprocketwhistle + [4226] = true, -- Ulthir + [7952] = true, -- Zjolnir + [465] = true, -- Barkeep Dobbins + [3364] = true, -- Borya + [5101] = true, -- Bryllia Ironbrand + [3096] = true, -- Captured Servant of Azora + [11038] = true, -- Caretaker Alen + [4167] = true, -- Dendrythis + [2812] = true, -- Drovnar Strongbrew + [4891] = true, -- Dwane Wertle + [1328] = true, -- Elly Langston + [3495] = true, -- Gagsprocket + [3547] = true, -- Hamlin Atkins + [15165] = true, -- Haughty Modiste + [11187] = true, -- Himmik + [295] = true, -- Innkeeper Farley + [6734] = true, -- Innkeeper Hearthstove + [1301] = true, -- Julia Gallina + [372] = true, -- Karm Ironquill + [8362] = true, -- Kuruk + [9099] = true, -- Sraaz + [5189] = true, -- Thrumn + [14522] = true, -- Ur'dan + [1685] = true, -- Xandar Goodbeard + [14637] = true, -- Zorbin Fandazzle + [9087] = true, -- Bashana Runetotem + [7978] = true, -- Bimble Longberry + [2838] = true, -- Crazk Sparks + [12021] = true, -- Daeolyn Summerleaf + [3577] = true, -- Dalaran Brewmaster + [233] = true, -- Farmer Saldean + [3367] = true, -- Felika + [5100] = true, -- Fillius Fizzlespinner + [5112] = true, -- Gwenna Firebrew + [3685] = true, -- Harb Clawhoof + [7733] = true, -- Innkeeper Fizzgrimble + [11103] = true, -- Innkeeper Lyshaerya + [12941] = true, -- Jase Farlane + [8121] = true, -- Jaxxil Sparks + [5783] = true, -- Kalldan Felmoon + [1456] = true, -- Kersok Prond + [5848] = true, -- Malgin Barleybrew + [2626] = true, -- Old Man Heming + [12796] = true, -- Raider Bork + [13432] = true, -- Seersa Copperpinch + [15199] = true, -- Sergeant Hartman + [5178] = true, -- Soolie Berryfizz + [14845] = true, -- Stamp Thunderhorn + [14844] = true, -- Sylannia + [3187] = true, -- Tai'tasi + [3366] = true, -- Tamar + [3313] = true, -- Trak'gen + [1678] = true, -- Vernon Hale + [1316] = true, -- Adair Gilroy + [2816] = true, -- Androd Fadran + [11287] = true, -- Baker Masterson + [274] = true, -- Barkeep Hann + [4168] = true, -- Elynna + [3881] = true, -- Grimtak + [15350] = true, -- Horde Warbringer + [11116] = true, -- Innkeeper Abeqwa + [3934] = true, -- Innkeeper Boorand Plainswind + [8150] = true, -- Janet Hommers + [15012] = true, -- Javnir Nashak + [8403] = true, -- Jeremiah Payson + [1318] = true, -- Jessara Cordell + [16256] = true, -- Jessica Chambers + [4589] = true, -- Joseph Moore + [14740] = true, -- Katoom the Angler + [3005] = true, -- Mahu + [5190] = true, -- Merill Pleasance + [4571] = true, -- Morley Bates + [2364] = true, -- Neema + [13018] = true, -- Nipsy + [2832] = true, -- Nixxrax Fillamug + [5193] = true, -- Rebecca Laughlin + [277] = true, -- Roberto Pupellyverbos + [7945] = true, -- Savanne + [4192] = true, -- Taldan + [3016] = true, -- Tand + [1460] = true, -- Unger Statforth + [2118] = true, -- Abigail Shiel + [5173] = true, -- Alexander Calder + [1321] = true, -- Alyssa Griffith + [12384] = true, -- Augustus the Touched + [12957] = true, -- Blimo Gadgetspring + [5128] = true, -- Bombus Finespindle + [2393] = true, -- Christoph Jeffcoat + [6374] = true, -- Cylina Darkheart + [12019] = true, -- Dargon + [2140] = true, -- Edwin Harly + [14481] = true, -- Emmithue Smails + [5483] = true, -- Erika Tate + [3090] = true, -- Gerald Crawley + [12958] = true, -- Gigget Zipcoil + [6731] = true, -- Harlown Darkweave + [4307] = true, -- Heldan Galesong + [2264] = true, -- Hillsbrad Tailor + [6736] = true, -- Innkeeper Keldamyr + [11106] = true, -- Innkeeper Sikewa + [384] = true, -- Katie Hunter + [5748] = true, -- Killian Sanatha + [3937] = true, -- Kira Songshine + [8305] = true, -- Kixxle + [15471] = true, -- Lieutenant General Andorov + [5757] = true, -- Lilly + [3961] = true, -- Maliynn + [2357] = true, -- Merideth Carlson + [12959] = true, -- Nergal + [8178] = true, -- Nina Lightbrew + [13420] = true, -- Penney Copperpinch + [8177] = true, -- Rartar + [982] = true, -- Thultash + [5169] = true, -- Tynnus Venomsprout + [4194] = true, -- Ullanna + [15011] = true, -- Wagner Hammerstrike + [5942] = true, -- Zansoa + [829] = true, -- Adlin Pridedrift + [6496] = true, -- Brivelthwerp + [5514] = true, -- Brooke Stonebraid + [2672] = true, -- Cowardly Crosby + [4894] = true, -- Craig Nollward + [6373] = true, -- Dane Winslow + [1304] = true, -- Darian Singh + [15197] = true, -- Darkcaller Yanka + [7940] = true, -- Darnall + [1453] = true, -- Dewin Shimmerdawn + [4587] = true, -- Elizabeth Van Talen + [3168] = true, -- Flakk + [2682] = true, -- Fradd Swiftgear + [3003] = true, -- Fyr Mistrunner + [3085] = true, -- Gloria Femmel + [4885] = true, -- Gregor MacVince + [3133] = true, -- Herble Baubbletump + [8931] = true, -- Innkeeper Heather + [1464] = true, -- Innkeeper Helbrek + [2388] = true, -- Innkeeper Shay + [7744] = true, -- Innkeeper Thulfram + [1325] = true, -- Jasper Fel + [3884] = true, -- Jhawna Oatwind + [5698] = true, -- Joanna Whitehall + [6382] = true, -- Jubahl Corpseseeker + [7772] = true, -- Kalin Windflight + [790] = true, -- Karen Taylor + [3958] = true, -- Lardan + [2383] = true, -- Lindea Rabonne + [1672] = true, -- Lohgan Eva + [5049] = true, -- Lyesa Steelbrow + [7955] = true, -- Milli Featherwhistle + [7879] = true, -- Quintis Jonespyre + [3499] = true, -- Ranik + [1457] = true, -- Samor Festivus + [8363] = true, -- Shadi Mistrunner + [5191] = true, -- Shalumon + [3333] = true, -- Shankys + [3089] = true, -- Sherman Femmel + [2622] = true, -- Sly Garrett + [8307] = true, -- Tarban Hearthgrain + [15124] = true, -- Targot Jinglepocket + [3935] = true, -- Toddrick + [4782] = true, -- Truk Wildbeard + [4875] = true, -- Turhaw + [1149] = true, -- Uthok + [15864] = true, -- Valadar Starsong + [13433] = true, -- Wulmort Jinglepocket + [3882] = true, -- Zlagk + [7683] = true, -- Alessandro Luca + [777] = true, -- Amy Davenport + [8158] = true, -- Bronk + [5570] = true, -- Bruuk Barleybeard + [8934] = true, -- Christopher Hewen + [1250] = true, -- Drake Lindgren + [4170] = true, -- Ellandrieth + [14963] = true, -- Gapp Jinglepocket + [6567] = true, -- Ghok'kah + [6301] = true, -- Gorbold Steelhand + [14437] = true, -- Gorzeeki Wildeyes + [13436] = true, -- Guchie Jinglepocket + [3956] = true, -- Harklan Moongrove + [894] = true, -- Homer Stonefield + [5111] = true, -- Innkeeper Firebrew + [6747] = true, -- Innkeeper Kauth + [1305] = true, -- Jarel Moor + [13430] = true, -- Jaycrue Copperpinch + [6730] = true, -- Jinky Twizzlefixxit + [2115] = true, -- Joshua Kien + [4615] = true, -- Katrina Alliestar + [13418] = true, -- Kaymard Copperpinch + [1237] = true, -- Kazan Mogosh + [5815] = true, -- Kurgul + [227] = true, -- Mabel Solaj + [13434] = true, -- Macey Jinglepocket + [1313] = true, -- Maria Lumere + [3480] = true, -- Moorane Hearthgrain + [2134] = true, -- Mrs. Winters + [12026] = true, -- My'lanna + [2683] = true, -- Namdo Bizzfizzle + [2380] = true, -- Nandar Branson + [2814] = true, -- Narj Deepslice + [3012] = true, -- Nata Dawnstrider + [8160] = true, -- Nioma + [4265] = true, -- Nyoma + [14450] = true, -- Orphan Matron Nightingale + [8681] = true, -- Outfitter Eric + [2699] = true, -- Rikqiz + [2684] = true, -- Rizz Loosebolt + [2688] = true, -- Ruppo Zipcoil + [4225] = true, -- Saenorion + [3548] = true, -- Selina Weston + [12794] = true, -- Stone Guard Zarg + [5135] = true, -- Svalbrad Farmountain + [3779] = true, -- Syurana + [3518] = true, -- Thomas Miller + [8117] = true, -- Wizbang Booms + [2670] = true, -- Xizk Goodstitch + [12956] = true, -- Zannok Hidepiercer + [14480] = true, -- Alowicious Czervik + [3350] = true, -- Asoran + [2366] = true, -- Barkeep Kelly + [5620] = true, -- Bartender Wental + [2846] = true, -- Blixrez Goodstitch + [3368] = true, -- Borstan + [4255] = true, -- Brogus Thunderbrew + [152] = true, -- Brother Danil + [4084] = true, -- Chylina + [4182] = true, -- Dalmond + [6091] = true, -- Dellylah + [3158] = true, -- Duokna + [5503] = true, -- Eldraeith + [4555] = true, -- Eleanor Rusk + [5160] = true, -- Emrul Riknussun + [4775] = true, -- Felicia Doan + [12795] = true, -- First Sergeant Hola'mahi + [5569] = true, -- Fizzlebang Booms + [4223] = true, -- Fyldan + [3298] = true, -- Gabrielle Chase + [16543] = true, -- Garon Hutchins + [843] = true, -- Gina MacGregor + [4256] = true, -- Golnir Bouldertoe + [1692] = true, -- Golorn Frostbeard + [3358] = true, -- Gorina + [2908] = true, -- Grawl + [8508] = true, -- Gretta Ganter + [5138] = true, -- Gwina Stonebranch + [3540] = true, -- Hal McAllister + [3962] = true, -- Haljan Oakheart + [8152] = true, -- Harnor + [6727] = true, -- Innkeeper Brianna + [7714] = true, -- Innkeeper Byula + [6272] = true, -- Innkeeper Janene + [6930] = true, -- Innkeeper Karakul + [12196] = true, -- Innkeeper Kaylisk + [6738] = true, -- Innkeeper Kimlya + [5688] = true, -- Innkeeper Renee + [9356] = true, -- Innkeeper Shul'kar + [5814] = true, -- Innkeeper Thulbek + [11118] = true, -- Innkeeper Vizzie + [3544] = true, -- Jason Lemieux + [4876] = true, -- Jawn Highmesa + [3498] = true, -- Jazzik + [4590] = true, -- Jonathan Chambers + [258] = true, -- Joshua Maclure + [6574] = true, -- Jun'ha + [15353] = true, -- Katrina Shimmerstar + [1697] = true, -- Keeg Gibn + [3348] = true, -- Kor'geld + [3329] = true, -- Kor'jus + [5870] = true, -- Krond + [1671] = true, -- Lamar Veisilli + [5871] = true, -- Larhka + [4730] = true, -- Lelanai + [8118] = true, -- Lillian Singh + [791] = true, -- Lindsay Ashlock + [1694] = true, -- Loslor Rudge + [15898] = true, -- Lunar Festival Vendor + [3587] = true, -- Lyrai + [2303] = true, -- Lyranne Feathersong + [2394] = true, -- Mallen Swain + [3010] = true, -- Mani Winterhoof + [7941] = true, -- Mardrack Greenwell + [1670] = true, -- Mike Miller + [13429] = true, -- Nardstrum Copperpinch + [7485] = true, -- Nargatt + [3614] = true, -- Narret Shadowgrove + [3014] = true, -- Nida Winterhoof + [14738] = true, -- Otho Moji'ko + [5132] = true, -- Pithwick + [5154] = true, -- Poranna Snowbraid + [15354] = true, -- Rachelle Gothena + [3541] = true, -- Sarah Raycroft + [955] = true, -- Sergeant De Vries + [3029] = true, -- Sewa Mistrunner + [3342] = true, -- Shan'ti + [2669] = true, -- Sheri Zipstitch + [5124] = true, -- Sognar Cliffbeard + [4221] = true, -- Talaelar + [1650] = true, -- Terry Palin + [4617] = true, -- Thaddeus Webb + [5158] = true, -- Tilli Thistlefuzz + [4195] = true, -- Tiyani + [4899] = true, -- Uma Bartulm + [4954] = true, -- Uttnar + [4189] = true, -- Valdaron + [4222] = true, -- Voloren + [13431] = true, -- Whulwert Copperpinch + [2842] = true, -- Wigcik + [8404] = true, -- Xan'tish + [4230] = true, -- Yldan + [8116] = true, -- Ziggle Sparks + [2225] = true, -- Zora Guthrek + [3608] = true, -- Aldia + [4191] = true, -- Allyndia + [3481] = true, -- Barg + [4893] = true, -- Bartender Lillian + [151] = true, -- Brog Hamfist + [2365] = true, -- Bront Coldcleave + [5163] = true, -- Burbik Gearspanner + [4216] = true, -- Chardryn + [4896] = true, -- Charity Mipsy + [12960] = true, -- Christi Galvanis + [2697] = true, -- Clyde Ranthal + [2668] = true, -- Danielle Zipstitch + [4266] = true, -- Danlyia + [3411] = true, -- Denni'ka + [2397] = true, -- Derak Nightfall + [15006] = true, -- Deze Snowbane + [14962] = true, -- Dillord Copperpinch + [3969] = true, -- Fahran Silentblade + [7942] = true, -- Faralorn + [3091] = true, -- Franklin Hamar + [3705] = true, -- Gahroot + [5750] = true, -- Gina Lang + [2820] = true, -- Graud + [4082] = true, -- Grawnal + [3291] = true, -- Greishan Ironstove + [12807] = true, -- Greshka + [3086] = true, -- Gretchen Vogel + [1452] = true, -- Gruham Rumdnul + [3708] = true, -- Gruna + [10216] = true, -- Gubber Blump + [960] = true, -- Gunder Thornbush + [5886] = true, -- Gwyn Farrow + [3933] = true, -- Hai'zan + [7943] = true, -- Harklane + [14964] = true, -- Hecht Copperpinch + [3948] = true, -- Honni Goldenoat + [12776] = true, -- Hraug + [9501] = true, -- Innkeeper Adegwa + [2352] = true, -- Innkeeper Anderson + [16458] = true, -- Innkeeper Faralia + [7737] = true, -- Innkeeper Greul + [6928] = true, -- Innkeeper Grosk + [6929] = true, -- Innkeeper Gryshka + [7731] = true, -- Innkeeper Jayka + [6737] = true, -- Innkeeper Shaussiy + [6807] = true, -- Innkeeper Skindle + [6791] = true, -- Innkeeper Wiley + [4169] = true, -- Jaeana + [3164] = true, -- Jark + [1311] = true, -- Joachim Brenlow + [5134] = true, -- Jonivera Farmountain + [3186] = true, -- K'waii + [3025] = true, -- Kaga Mistrunner + [3487] = true, -- Kalyimah Stormcloud + [3072] = true, -- Kawnie Softbreeze + [5749] = true, -- Kayla Smithe + [2401] = true, -- Kayren Soothallow + [13435] = true, -- Khole Jinglepocket + [6027] = true, -- Kitha + [8122] = true, -- Kizzak Sparks + [15125] = true, -- Kosco Copperpinch + [1691] = true, -- Kreg Bilmn + [3621] = true, -- Kurll + [3002] = true, -- Kurm Stonehoof + [3561] = true, -- Kyrai + [3689] = true, -- Laer Stepperunner + [12028] = true, -- Lah'Mawhani + [14731] = true, -- Lard + [8143] = true, -- Loorana + [11186] = true, -- Lunnix Sprocketslip + [12031] = true, -- Mai'Lahii + [3135] = true, -- Malissa + [3044] = true, -- Miles Welsh + [4577] = true, -- Millie Gregorian + [14961] = true, -- Mirvyna Jinglepocket + [3883] = true, -- Moodan Sungrain + [3076] = true, -- Moorat Longstride + [3017] = true, -- Nan Mistrunner + [3959] = true, -- Nantar + [2084] = true, -- Natheril Raincaller + [3312] = true, -- Olvia + [8364] = true, -- Pakwa + [3551] = true, -- Patrice Dwyer + [491] = true, -- Quartermaster Lewis + [1474] = true, -- Rann Flamespinner + [3625] = true, -- Rarck + [6495] = true, -- Riznek + [4599] = true, -- Sarah Killian + [3138] = true, -- Scott Carevin + [10367] = true, -- Shrye Ragefist + [5520] = true, -- Spackle Thornberry + [3178] = true, -- Stuart Fleming + [4554] = true, -- Tawny Grisette + [6298] = true, -- Thelgrum Stonehammer + [12027] = true, -- Tukk + [4228] = true, -- Vaean + [2808] = true, -- Vikki Lonsav + [6568] = true, -- Vizzklick + [12962] = true, -- Wik'Tar + [3485] = true, -- Wrahk + [6376] = true, -- Wren Darkspring + [3400] = true, -- Xen'to + [5944] = true, -- Yonada + [3572] = true, -- Zizzek + [18960] = true, -- Rungor + [18484] = true, -- Wind Trader Lathrai + [18911] = true, -- Juno Dufrain + [18756] = true, -- Haris Pilton + [19663] = true, -- Madame Ruby + [19186] = true, -- Kylene + [27721] = true, -- Drelik Blastpipe + [19213] = true, -- Eiin + [27722] = true, -- Drolig Blastpipe + [18753] = true, -- Felannia + [20097] = true, -- Nula the Butcher + [20028] = true, -- Doba + [18015] = true, -- Gambarinka + [21655] = true, -- Nakodu + [20096] = true, -- Uriku + [19837] = true, -- Daga Ramba + [23604] = true, -- Agnes Farwithers + [20080] = true, -- Galgrom + [18751] = true, -- Kalaen + [27668] = true, -- Ontok Shatterhorn + [19321] = true, -- Quartermaster Endarin + [21643] = true, -- Alurmi + [16585] = true, -- Cookie One-Eye + [18773] = true, -- Johan Barnes + [16826] = true, -- Sid Limbardi + [18005] = true, -- Haalrun + [19227] = true, -- Griftah + [18525] = true, -- G'eras + [18774] = true, -- Tatiana + [18775] = true, -- Lebowski + [16782] = true, -- Yatheon + [21432] = true, -- Almaador + [16602] = true, -- Floyd Pinkus + [19296] = true, -- Innkeeper Biribi + [19331] = true, -- Quartermaster Enuril + [17585] = true, -- Quartermaster Urgronn + [18988] = true, -- Baxter + [19196] = true, -- Cro Threadstrong + [17657] = true, -- Logistics Officer Ulrike + [19661] = true, -- Viggz Shinesparked + [18898] = true, -- Explodyne Fizzlespurt + [20807] = true, -- Scribe Saalyn + [19042] = true, -- Leeli Longhaggle + [16689] = true, -- Zaralda + [18987] = true, -- Gaston + [16657] = true, -- Feera + [20808] = true, -- Scribe Veredis + [25976] = true, -- Theremis + [18990] = true, -- Burko + [20981] = true, -- Dealer Najeeb + [16860] = true, -- Jilanne + [16635] = true, -- Lyna + [16253] = true, -- Master Chef Mouldier + [17584] = true, -- Torallius the Pack Handler + [25178] = true, -- Ecton Brasstumbler + [18957] = true, -- Innkeeper Grilka + [19074] = true, -- Skreah + [20278] = true, -- Vixton Pinchwhistle + [18266] = true, -- Warrant Officer Tracy Proudwell + [18991] = true, -- Aresella + [20986] = true, -- Dealer Tariq + [23489] = true, -- Drake Dealer Hurlunk + [25032] = true, -- Eldara Dawnrunner + [19772] = true, -- Spirit Sage Gartok + [20916] = true, -- Xerintha Ravenoak + [18255] = true, -- Apprentice Darius + [16641] = true, -- Melaris + [22212] = true, -- Andrion Darkspinner + [16262] = true, -- Landraelanis + [19038] = true, -- Supply Officer Mills + [20980] = true, -- Dealer Rashaad + [16722] = true, -- Egomis + [19773] = true, -- Spirit Sage Zran + [16367] = true, -- Botanist Tyniarrel + [18906] = true, -- Caregiver Ophera Windfury + [19053] = true, -- Fabian Lanzonelli + [18907] = true, -- Innkeeper Coryth Stoktron + [18993] = true, -- Naka + [22208] = true, -- Nasmara Moonsong + [20989] = true, -- Dealer Sadaqat + [16224] = true, -- Rathis Tomber + [24934] = true, -- Snack-O-Matic IV + [27817] = true, -- Brew Vendor + [18771] = true, -- Brumman + [20494] = true, -- Dama Wildmane + [24408] = true, -- Gunter + [23484] = true, -- Haldor the Compulsive + [19065] = true, -- Inessera + [23521] = true, -- Anne Summers + [18267] = true, -- Battlecryer Blackeye + [26352] = true, -- Big Zokk Torquewrench + [18772] = true, -- Hama + [18564] = true, -- Horde Field Scout + [19182] = true, -- Shaarubo + [18897] = true, -- "King" Dond + [23245] = true, -- Aether-tech Master + [19617] = true, -- Boots + [17421] = true, -- Clopper Wizbang + [19857] = true, -- Meminnie + [26092] = true, -- Soryn + [19245] = true, -- Vinemaster Alamaro + [18018] = true, -- Zurjaya + [18542] = true, -- Alexston Chrome + [19521] = true, -- Arrond + [18754] = true, -- Barim Spilthoof + [23263] = true, -- Brendan Turner + [19534] = true, -- Dealer Digriz + [17101] = true, -- Diktynna + [18427] = true, -- Fazu + [16766] = true, -- Issca + [22270] = true, -- Ogri'la Merchant + [22271] = true, -- Ogri'la Trader + [21019] = true, -- Sixx + [18752] = true, -- Zebig + [17246] = true, -- "Cookie" McWeaksauce + [19017] = true, -- Borto + [18914] = true, -- Caregiver Isel + [16709] = true, -- Cuzi + [18749] = true, -- Dalinna + [19197] = true, -- Eral + [25179] = true, -- Frixee Brasstumbler + [24993] = true, -- Galley Chief Mariss + [19050] = true, -- Garul + [16444] = true, -- Halis Dawnstrider + [18929] = true, -- Kyrenna + [15397] = true, -- Marniel Amberlight + [27666] = true, -- Ontuvo + [18821] = true, -- Quartermaster Jaffrey Noreliqe + [18947] = true, -- Solanin + [19244] = true, -- Trader Endernor + [25034] = true, -- Tradesman Portanuus + [16264] = true, -- Winaestra + [21488] = true, -- Banro + [21111] = true, -- Bembil Knockhammer + [20510] = true, -- Brunn Flamebeard + [18251] = true, -- Caregiver Abidaar + [16267] = true, -- Daestra + [18959] = true, -- Dod'ss + [24510] = true, -- Driz Tumblequick + [16268] = true, -- Eralan + [16624] = true, -- Gelanthis + [22213] = true, -- Gidge Spellweaver + [23437] = true, -- Indormi + [18908] = true, -- Innkeeper Kerp + [23428] = true, -- Jho'nass + [26124] = true, -- Midsummer Merchant + [16768] = true, -- Nurguni + [20241] = true, -- Provisioner Nasela + [21113] = true, -- Sassa Weldwell + [23606] = true, -- Suntouched Apprentice + [25977] = true, -- Yrma + [19234] = true, -- Yurial Soulwater + [17512] = true, -- Arred + [19540] = true, -- Asarnan + [24495] = true, -- Blix Fixwidget + [27814] = true, -- Brew Vendor + [27818] = true, -- Brew Vendor + [23605] = true, -- Bron + [16739] = true, -- Caregiver Breel + [25176] = true, -- Grikkin Copperspring + [19232] = true, -- Innkeeper Haelthol + [19195] = true, -- Jim Saltit + [19345] = true, -- Kalara + [19474] = true, -- Karnaze + [21906] = true, -- Kelara + [23699] = true, -- Kevin Browning + [24392] = true, -- Leeni "Smiley" Smalls + [25195] = true, -- Marksman Bova + [19015] = true, -- Mathar G'ochar + [26123] = true, -- Midsummer Supplier + [16767] = true, -- Neii + [19045] = true, -- Oloraak + [19372] = true, -- Oran Blusterbrew + [21744] = true, -- Roldemar + [23510] = true, -- Thunderbrew Apprentice + [20240] = true, -- Trader Narasu + [21905] = true, -- Veynna Dawnstar + [16442] = true, -- Vinemaster Suntouched + [15494] = true, -- Yasmine Teli'Larien + [24208] = true, -- "Little" Logok + [18664] = true, -- Aged Dalaran Wizard + [19932] = true, -- Andormu + [20249] = true, -- Cymbre Starsong + [16708] = true, -- Dekin + [19495] = true, -- Innkeeper Shaunessy + [26089] = true, -- Kayri + [23396] = true, -- Krixel Pinchwhistle + [27478] = true, -- Larkin Thunderbrew + [26395] = true, -- Lieutenant Tristia + [24975] = true, -- Mar'nah + [16613] = true, -- Parnis + [19562] = true, -- Peon Bolgar + [16718] = true, -- Phea + [24468] = true, -- Pol Amberstill + [16187] = true, -- Quartermaster Lymel + [27489] = true, -- Ray'ma + [23363] = true, -- Sahaak + [16649] = true, -- Torian + [16443] = true, -- Zalene Firstlight + [23244] = true, -- Aether-tech Adept + [23243] = true, -- Aether-tech Assistant + [23483] = true, -- Arcanist Xorith + [23522] = true, -- Arlen Lochlan + [17222] = true, -- Artificer Daelo + [19371] = true, -- Dalin Stouthammer + [16683] = true, -- Darlia + [19538] = true, -- Dealer Senzik + [25177] = true, -- Evee Copperspring + [21110] = true, -- Fizit "Doc" Clocktock + [17630] = true, -- Innkeeper Jovia + [16618] = true, -- Innkeeper Velandra + [19539] = true, -- Jazdalaad + [23748] = true, -- Kurzel + [21145] = true, -- Little Azimi + [23535] = true, -- Matero Zeshuwal + [19664] = true, -- Muffin Man Moser + [22266] = true, -- Ogri'la Grubgiver + [18810] = true, -- Otonambusi + [19450] = true, -- Pol Snowhoof + [17277] = true, -- Provisioner Valine + [15287] = true, -- Shara Sunwing + [23010] = true, -- Wolgren Jinglepocket + [23896] = true, -- "Dirty" Michael Crowe + [18581] = true, -- Alliance Field Scout + [23995] = true, -- Axle + [20377] = true, -- Barkeep Kelly + [23482] = true, -- Barleybrew Apprentice + [23710] = true, -- Belbi Quikswitch + [16650] = true, -- Bithrus + [27810] = true, -- Brew Vendor + [27820] = true, -- Brew Vendor + [27806] = true, -- Brew Vendor + [25036] = true, -- Caregiver Inaara + [21487] = true, -- Cendrii + [20378] = true, -- Chef Jessen + [19435] = true, -- Dark Cleric Malod + [19537] = true, -- Dealer Malij + [16638] = true, -- Deynna + [19649] = true, -- Dorni + [19352] = true, -- Dreg Cloudsweeper + [24501] = true, -- Drohn's Distillery Apprentice + [23064] = true, -- Eebee Jinglepocket + [21484] = true, -- Embelar + [17490] = true, -- Ergh of the Stillpine + [21083] = true, -- Erool + [19531] = true, -- Eyonix + [19518] = true, -- Feranin + [25012] = true, -- Galley Chief Gathers + [24834] = true, -- Galley Chief Grace + [25089] = true, -- Galley Chief Steelbelly + [19572] = true, -- Gant + [19470] = true, -- Gholah + [19223] = true, -- Granny Smith + [28225] = true, -- Griz Gutshank + [16748] = true, -- Haferet + [18905] = true, -- Innkeeper Bazil Olof'tazun + [16610] = true, -- Kredis + [19330] = true, -- Lisrythe Bloodwatch + [18913] = true, -- Matron Tikkit + [18811] = true, -- Meriaad + [16751] = true, -- Merran + [19559] = true, -- Mondul + [20893] = true, -- Morula + [23110] = true, -- Ogri'la Keg King + [23065] = true, -- Olnayvi Copperpinch + [26091] = true, -- Olus + [16732] = true, -- Onnis + [18009] = true, -- Puluu + [18822] = true, -- Quartermaster Davian Vaclav + [20892] = true, -- Ruogo + [16920] = true, -- Ryosh + [19374] = true, -- Salle Sunforge + [21172] = true, -- Sarinei Whitestar + [16366] = true, -- Sempstress Ambershine + [16259] = true, -- Sheri + [23533] = true, -- T'chali's Voodoo Brewery Apprentice + [19498] = true, -- Tanaide + [21483] = true, -- Tasaldan + [24545] = true, -- Thunderbrew "Apprentice" + [25035] = true, -- Tyrael Flamekissed + [16664] = true, -- Zelan + [19625] = true, -- Alorya + [16705] = true, -- Altaa + [16713] = true, -- Arras + [23009] = true, -- Bessbi Jinglepocket + [21084] = true, -- Braagor + [27816] = true, -- Brew Vendor + [27811] = true, -- Brew Vendor + [27819] = true, -- Brew Vendor + [23525] = true, -- Brother Cartwright + [19497] = true, -- Caoileann + [16553] = true, -- Caregiver Chellan + [17553] = true, -- Caregiver Topher Loaal + [21746] = true, -- Caretaker Aluuro + [19573] = true, -- Dash + [19533] = true, -- Dealer Aljaan + [20194] = true, -- Dealer Dunar + [19532] = true, -- Dearny + [18951] = true, -- Erilia + [19194] = true, -- Ernie Packwell + [20121] = true, -- Fingin + [25020] = true, -- Galley Chief Alunwea + [25052] = true, -- Galley Chief Halumvorea + [23511] = true, -- Gordok Brew Apprentice + [17656] = true, -- Heron Skygaze + [23143] = true, -- Horus + [15433] = true, -- Innkeeper Delaniel + [16542] = true, -- Innkeeper Kalarin + [19049] = true, -- Karokka + [26090] = true, -- Karynna + [23481] = true, -- Keiran Donoghue + [18277] = true, -- Kinamisa + [19574] = true, -- Kizzie + [23573] = true, -- Krixil Slogswitch + [21082] = true, -- Krugash + [17489] = true, -- Logan Daniel + [19560] = true, -- Lukra + [19020] = true, -- Matron Qualia + [18245] = true, -- Merajit + [19836] = true, -- Mixie Farshot + [19722] = true, -- Muheru the Weaver + [19243] = true, -- Nalama the Merchant + [19021] = true, -- Nancila + [19528] = true, -- Nanomah + [19471] = true, -- Old Orok + [18347] = true, -- Olirea + [17446] = true, -- Parkat Steelfur + [16798] = true, -- Provisioner Anir + [19451] = true, -- Quartermaster Gorman + [16677] = true, -- Quelis + [21085] = true, -- Ragar + [20250] = true, -- Rashere Pridehoof + [16690] = true, -- Rathin + [18954] = true, -- Sailor Melinan + [16191] = true, -- Sathren Azuredawn + [25043] = true, -- Sereth Duskbringer + [25950] = true, -- Shaani + [20891] = true, -- Skraa + [23208] = true, -- Skyguard Pyrotechnician + [19348] = true, -- Targrom + [19472] = true, -- Threlc + [19343] = true, -- Trop Rendlimb + [23603] = true, -- Uta Roughdough + [17486] = true, -- Ziz + [32538] = true, -- Duchess Mynx + [32216] = true, -- Mei Francis + [30431] = true, -- Veteran Crusader Aliocha Segard + [32540] = true, -- Lillehoff + [199387] = true, -- D[3] = true-BA + [31247] = true, -- Roxi Ramrocket + [31238] = true, -- Hira Snowdawn + [32287] = true, -- Archmage Alvareaux + [32533] = true, -- Cielstrasza + [32763] = true, -- Sairuk + [34885] = true, -- Dame Evniki Kapsalis + [31916] = true, -- Tanaika + [28715] = true, -- Endora Moorehead + [32296] = true, -- Stone Guard Mukar + [40160] = true, -- Frozo the Renowned + [32565] = true, -- Gara Skullcrush + [32172] = true, -- Harold Winston + [32294] = true, -- Knight Dameron + [32564] = true, -- Logistics Officer Silverstone + [211332] = true, -- Korralin Hoperender + [211340] = true, -- Kolara Dreamsmasher + [28742] = true, -- Marcia Chase + [207128] = true, -- Animated Constellation + [33557] = true, -- Trellis Morningsun + [31580] = true, -- Arcanist Ivrenne + [33555] = true, -- Eliza Killian + [31910] = true, -- Geen + [29587] = true, -- Dread Commander Thalanor + [32774] = true, -- Sebastian Crane + [35494] = true, -- Arcanist Miluria + [31582] = true, -- Magistrix Lambriesse + [35826] = true, -- Kaye Toogie + [28701] = true, -- Timothy Jones + [33634] = true, -- Engineer Sinbei + [33653] = true, -- Rook Hawkfist + [32515] = true, -- Braeg Stoutbeard + [33682] = true, -- Fono + [33963] = true, -- Magister Sarien + [32773] = true, -- Logistics Officer Brighton + [33553] = true, -- Freka Bloodaxe + [32509] = true, -- Brammold Deepmine + [32514] = true, -- Vanessa Sellers + [33640] = true, -- Hanlir + [33554] = true, -- Samamba + [35508] = true, -- Enchanter Erodin + [35507] = true, -- Enchanter Isian + [33307] = true, -- Corporal Arthur Flew + [33650] = true, -- Rillie Spindlenut + [30730] = true, -- Stanly McCormick + [33310] = true, -- Derrick Brindlebeard + [33657] = true, -- Irisee + [35577] = true, -- Valiant Laradia + [33026] = true, -- Sarah Brady + [29535] = true, -- Alchemist Cinesra + [29744] = true, -- Rork Sharpchin + [35578] = true, -- Valiant Bressia + [37941] = true, -- Magister Arlan + [31031] = true, -- Misensi + [31032] = true, -- Derek Odds + [34772] = true, -- Vasarin Redmorn + [29493] = true, -- Jarold Puller + [32380] = true, -- Lieutenant Tristia + [37942] = true, -- Arcanist Uovril + [32836] = true, -- Noblegarden Vendor + [28776] = true, -- Elizabeth Ross + [27760] = true, -- "Grizzly" D. Adams + [31581] = true, -- Magister Brasael + [30472] = true, -- Olut Alegut + [28721] = true, -- Tiffany Cartier + [28687] = true, -- Amisi Azuregaze + [29478] = true, -- Jepetto Joybuzz + [31579] = true, -- Arcanist Adurin + [28951] = true, -- Breanni + [30723] = true, -- Xantili + [32382] = true, -- Lady Palanseer + [27730] = true, -- Purkom + [33556] = true, -- Doru Thunderhorn + [33636] = true, -- Miralisse + [32837] = true, -- Noblegarden Merchant + [29547] = true, -- Applebough + [30885] = true, -- Blazik Fireclaw + [28726] = true, -- Dominique Stefano + [32413] = true, -- Isirami Fairwind + [29628] = true, -- Angelique Butler + [35580] = true, -- Aspirant Naradiel + [26110] = true, -- Librarian Serrah + [35575] = true, -- Champion Isimode + [35495] = true, -- Magistrix Vesara + [33595] = true, -- Mera Mistrunner + [26977] = true, -- Adelene Sunlance + [34881] = true, -- Hiren Loresong + [32354] = true, -- Leeni "Smiley" Smalls + [37674] = true, -- Lovely Merchant + [29532] = true, -- Ajay Green + [29491] = true, -- Karandonna + [28993] = true, -- Aerith Primrose + [35099] = true, -- Bana Wildmane + [32337] = true, -- Christi Stockton + [32362] = true, -- Evee Copperspring + [33027] = true, -- Jessica Sellers + [33964] = true, -- Arcanist Firael + [26484] = true, -- Hugh Glass + [33679] = true, -- Recorder Lidio + [31911] = true, -- Tanak + [33677] = true, -- Technician Mihila + [33996] = true, -- William Saldean + [31557] = true, -- Uda the Beast + [33631] = true, -- Barien + [35576] = true, -- Champion Faesrol + [26938] = true, -- Groll + [33638] = true, -- Scribe Lanloer + [33684] = true, -- Weaver Aoa + [24539] = true, -- "Silvermoon" Harry + [29716] = true, -- Clockwork Assistant + [33853] = true, -- Broxel Goldgrasp + [29715] = true, -- Fialla Sweetberry + [28347] = true, -- Miles Sidney + [29495] = true, -- Norvin Alderman + [39173] = true, -- Champion Ros'slai + [28692] = true, -- "Red" Jack Findle + [32355] = true, -- Big Zokk Torquewrench + [32379] = true, -- Captain O'Neal + [29528] = true, -- Debbi Moore + [33678] = true, -- Jijia + [26995] = true, -- Tink Brightbolt + [25248] = true, -- "Salty" John Thorpe + [35574] = true, -- Magistrix Iruvia + [29527] = true, -- Orton Bennet + [24291] = true, -- Anton + [33637] = true, -- Kirembri Silvermane + [34682] = true, -- Wilmina Holbeck + [33596] = true, -- Meline Duskpath + [28718] = true, -- Ranid Glowergold + [29122] = true, -- Rarkag + [29548] = true, -- Aimee + [32359] = true, -- Argex Irongut + [35579] = true, -- Aspirant Forudir + [35131] = true, -- Durgan Thunderbeak + [26959] = true, -- Booker Kells + [26718] = true, -- Trader Alorn + [30488] = true, -- Travis Day + [32356] = true, -- Kezzik the Striker + [28723] = true, -- Larana Drome + [29529] = true, -- Ninsianna + [26868] = true, -- Provisioner Lorkran + [34382] = true, -- Chapman + [29277] = true, -- Datalore Smallsphere + [32415] = true, -- Hamaka + [32642] = true, -- Mojodishu + [33680] = true, -- Nemiha + [33675] = true, -- Onodo + [30011] = true, -- Sigdis the Trader + [27193] = true, -- Alornerk + [33602] = true, -- Anuur + [29702] = true, -- Chameli Banaphash + [35101] = true, -- Grunda Bronzewing + [28868] = true, -- Mulch + [35573] = true, -- Arcanist Asarina + [29208] = true, -- Fester + [31101] = true, -- Hoodoo Master Fu'jin + [34683] = true, -- Rose Standish + [28691] = true, -- Susana Averoy + [24342] = true, -- Timothy Holland + [29270] = true, -- Aspen Grove Trader + [24054] = true, -- Balar Rumsbane + [194795] = true, -- Fishspeaker Irtusk + [28046] = true, -- Korg the Cleaver + [39172] = true, -- Marshal Magruder + [32420] = true, -- Mimbihi + [26916] = true, -- Mindri Dinkles + [27144] = true, -- Noatak + [28792] = true, -- Noggra + [29261] = true, -- Windle Sparkshine + [32631] = true, -- Alfred Copperworth + [29275] = true, -- Aspen Grove Supplier + [24341] = true, -- Barnabas Frye + [33639] = true, -- Botanist Alaenra + [35343] = true, -- Bountiful Barrel + [35341] = true, -- Bountiful Barrel + [26941] = true, -- Brokkan Bear-Arms + [29207] = true, -- Gangrenus + [32638] = true, -- Hakmud of Argus + [34681] = true, -- Ikaneba Summerset + [30735] = true, -- Kul Inkspiller + [30724] = true, -- Mertle Murkpen + [27938] = true, -- Trizormu + [25278] = true, -- Williamson + [30098] = true, -- Amphitheater Vendor + [35342] = true, -- Bountiful Barrel + [34685] = true, -- Dalni Tallgrass + [29291] = true, -- Galley Chief Paul Kubit + [29905] = true, -- Grillix Bonesaw + [28589] = true, -- Gristlegut + [30254] = true, -- Marisalira + [30489] = true, -- Morgan Day + [29908] = true, -- Plip Fatpurse + [28038] = true, -- Purser Boulian + [27022] = true, -- Afha + [28707] = true, -- Angelo Pescatore + [29049] = true, -- Arille Azuregaze + [35337] = true, -- Bountiful Barrel + [199649] = true, -- Crafted Gearataur + [32360] = true, -- Ecton Brasstumbler + [27142] = true, -- Librarian Jeffers + [33597] = true, -- Liere Morningsong + [26709] = true, -- Pahu Frosthoof + [29583] = true, -- Pan'ya + [29703] = true, -- Sheddle Glossgleam + [31051] = true, -- Sorceress Kaylana + [27146] = true, -- Uukkarnit + [29512] = true, -- Ainderu Summerleaf + [27031] = true, -- Apothecary Rose + [27187] = true, -- Caregiver Poallu + [24057] = true, -- Christina Daniels + [28869] = true, -- Deathdrip + [30729] = true, -- Ickabod Pimlen + [30731] = true, -- Illianna Moonscribe + [23937] = true, -- Innkeeper Celeste Goodhutch + [29121] = true, -- Soo-yum + [31021] = true, -- Sophie Aaren + [27145] = true, -- Tipvigut + [35132] = true, -- Tohfo Skyhoof + [32419] = true, -- Umbiwa + [28994] = true, -- Abra Cadabra + [26680] = true, -- Aiyan Coldwind + [33866] = true, -- Akrittok + [27125] = true, -- Barracks Master Rhekku + [30306] = true, -- Bileblow + [35338] = true, -- Bountiful Barrel + [27174] = true, -- Caregiver Mumik + [28798] = true, -- Claudia Bloodraven + [29205] = true, -- Corpulous + [28682] = true, -- Inzi Charmlight + [29244] = true, -- Jesse Masters + [33681] = true, -- Korim + [26939] = true, -- Koro the Wanderer + [30727] = true, -- Lelorian + [27940] = true, -- Lethecus + [27147] = true, -- Librarian Erickson + [27070] = true, -- Lisa Philbrook + [28685] = true, -- Narisa Redgold + [28725] = true, -- Patricia Egan + [27182] = true, -- Takubvik + [27195] = true, -- Tarralikitak + [27063] = true, -- Vrok + [29971] = true, -- Wabada Whiteflower + [26945] = true, -- Zend'li Venomtusk + [26596] = true, -- "Charlie" Northtop + [27148] = true, -- Caregiver Iqniq + [26936] = true, -- Chaska Frosthoof + [33635] = true, -- Daenril + [28727] = true, -- Edward Egan + [24053] = true, -- Helga Rumsbane + [29962] = true, -- Horgoru the Collector + [23731] = true, -- Innkeeper Hazel Lagras + [25245] = true, -- James Deacon + [34684] = true, -- Laha Farplain + [29510] = true, -- Linna Bruder + [30005] = true, -- Lodge-Matron Embla + [29963] = true, -- Magorn + [33865] = true, -- Makuli + [31017] = true, -- Mal Corricks + [30311] = true, -- Mangled + [32421] = true, -- Marcella Bloom + [33019] = true, -- Megan Owings + [27181] = true, -- Qannik + [27132] = true, -- Sani'i + [30256] = true, -- Scout Ordimbral + [30257] = true, -- Scout Yribria + [29904] = true, -- Smilin' Slirk Brassknob + [28867] = true, -- Spiked + [28872] = true, -- Squirmworm + [24147] = true, -- Tara Cooper + [33872] = true, -- Torgah + [27021] = true, -- Tradesman Kontor + [26567] = true, -- Aegalas + [28828] = true, -- Ansari + [24333] = true, -- Bartender Jason Goodhutch + [27012] = true, -- Beem Goldsprocket + [27071] = true, -- Benjamin Jacobs + [24033] = true, -- Bori Wintertotem + [35340] = true, -- Bountiful Barrel + [24343] = true, -- Brock Olson + [33600] = true, -- Cerie Larksong + [32426] = true, -- Coira Longrifle + [23737] = true, -- Coot "The Stranger" Albertson + [30437] = true, -- Crusader Marisse + [29970] = true, -- Danho Farcloud + [24148] = true, -- David Marks + [27950] = true, -- Demestrasz + [28728] = true, -- Dorian Fines + [33683] = true, -- Dremm + [27038] = true, -- Drolfy + [33601] = true, -- Elka Stormbrew + [33644] = true, -- Ellia Moondancer + [27041] = true, -- Fanny McLumpkins + [30346] = true, -- Galley Chief Dolinger + [31022] = true, -- George Goodman + [29926] = true, -- Gunda Boldhammer + [27042] = true, -- Illusia Lune + [27184] = true, -- Imnek + [30070] = true, -- Initiate Gahark + [33645] = true, -- Jenna Thunderbrew + [33018] = true, -- Jennifer Owings + [29511] = true, -- Lalla Brightweave + [27053] = true, -- Lanus Longleaf + [28812] = true, -- Lapu Stormhorn + [27143] = true, -- Librarian Ingram + [27032] = true, -- Lovely Liddia + [29714] = true, -- Lucian Trias + [26374] = true, -- Maevin Farmoon + [27052] = true, -- Naohain + [32334] = true, -- Nixi Fireclaw + [29944] = true, -- Peon Gakra + [26375] = true, -- Quartermaster McCarty + [28830] = true, -- Ra'wiri + [27026] = true, -- Rohesia Werner + [32403] = true, -- Sandra Bartan + [27057] = true, -- Saramer Whitewillow + [28829] = true, -- Saree + [30732] = true, -- Sessoh + [30309] = true, -- Shambles + [30439] = true, -- Sister Colleen Tulley + [32416] = true, -- Stefen Cotter + [24141] = true, -- Stephen Barone + [30733] = true, -- Thargen Heavyquill + [27043] = true, -- Trixy Trixerton + [30827] = true, -- Utamu + [26388] = true, -- Veira Langdon + [23802] = true, -- Wink Sprinklesprankle + [26568] = true, -- Zebu'tan + [28799] = true, -- Alanna + [28807] = true, -- Amarante + [30255] = true, -- Aniduria + [27137] = true, -- Apprentice Fraser + [24149] = true, -- Basil Osgood + [30310] = true, -- Boltskull + [28811] = true, -- Brady Ironcrock + [28806] = true, -- Chad Carter + [28832] = true, -- Chin'ika + [28866] = true, -- Corrosion + [26720] = true, -- Danook Stormwhisper + [27051] = true, -- Doldaen + [34645] = true, -- Elizabeth Barker Winslow + [33598] = true, -- Fanii + [24356] = true, -- Glen Roberts + [27025] = true, -- Harold Haggler + [27066] = true, -- Jennifer Bell + [30734] = true, -- Jezebel Bican + [28794] = true, -- Kevin Weaver + [27058] = true, -- Korag Keeneye + [32424] = true, -- Laire Brewgold + [28810] = true, -- Lessien + [27140] = true, -- Librarian Andersen + [27141] = true, -- Librarian Hamilton + [28791] = true, -- Marissa Everwatch + [32412] = true, -- Mato + [27069] = true, -- Matron Magah + [27027] = true, -- Mrs. Winterby + [27044] = true, -- Ordal McLumpkins + [24348] = true, -- Patrick Hall + [34783] = true, -- Ranisa Whitebough + [29925] = true, -- Rutner Steelpick + [27089] = true, -- Saffron Reynolds + [32478] = true, -- Slosh + [23732] = true, -- Sorely Twitchblade + [31019] = true, -- Stephanie Sindree + [33868] = true, -- Tingiyok + [33869] = true, -- Torngasak + [27190] = true, -- Tupit + [28831] = true, -- Yamuna }, } \ No newline at end of file diff --git a/Modules/Nameplates/NameLevel.lua b/Modules/Nameplates/NameLevel.lua index f1cd223..c2bcf1e 100644 --- a/Modules/Nameplates/NameLevel.lua +++ b/Modules/Nameplates/NameLevel.lua @@ -414,9 +414,9 @@ function mod:Toggle(db) end for i, element in ipairs({'Name', 'Level'}) do if db[type][element].enabled then - enabled[element] = true + enabled[element] = not core.reload if i == 1 and not db[type][element].toLevel then - enabled['nameshorten'] = true + enabled['nameshorten'] = not core.reload end end end diff --git a/Modules/Nameplates/QuestIcons.lua b/Modules/Nameplates/QuestIcons.lua index d3eb408..d312f8e 100644 --- a/Modules/Nameplates/QuestIcons.lua +++ b/Modules/Nameplates/QuestIcons.lua @@ -13,7 +13,7 @@ local _G, pairs, ipairs, unpack, tonumber = _G, pairs, ipairs, unpack, tonumber local find, match, format, lower = string.find, string.match, string.format, string.lower local tinsert, twipe = table.insert, table.wipe local UnitName, UnitIsPlayer = UnitName, UnitIsPlayer -local GetQuestLink, GetQuestLogLeaderBoard, GetQuestLogTitle = GetQuestLink, GetQuestLogLeaderBoard, GetQuestLogTitle +local GetQuestLogLeaderBoard, GetQuestLogTitle = GetQuestLogLeaderBoard, GetQuestLogTitle local GetNumQuestLogEntries, GetNumQuestLeaderBoards = GetNumQuestLogEntries, GetNumQuestLeaderBoards local THREAT_TOOLTIP = gsub(THREAT_TOOLTIP, '%%d', '%%d-') @@ -117,9 +117,9 @@ function mod:LoadConfig() local db = E.db.Extras.nameplates[modName] local function populateModifierValues(othervala, othervalb) local modsList = {} - for mod, val in pairs(E.db.Extras.modifiers) do - if mod ~= 'ANY' and db.modifiers[othervala] ~= mod and db.modifiers[othervalb] ~= mod then - modsList[mod] = val + for modifier, val in pairs(E.db.Extras.modifiers) do + if modifier ~= 'ANY' and db.modifiers[othervala] ~= modifier and db.modifiers[othervalb] ~= modifier then + modsList[modifier] = val end end if db.modifiers[othervala] ~= 'NONE' and db.modifiers[othervalb] ~= 'NONE' then @@ -721,7 +721,7 @@ function mod:Toggle(db) self:UnregisterAllEvents() twipe(markedUnits) - if db.enabled then + if not core.reload and db.enabled then core.plateAnchoring['questIcon'] = function() return db end SLASH_QMARK1 = "/qmark" diff --git a/Modules/Nameplates/StyleFilter.lua b/Modules/Nameplates/StyleFilter.lua index 92770a2..591be8e 100644 --- a/Modules/Nameplates/StyleFilter.lua +++ b/Modules/Nameplates/StyleFilter.lua @@ -6,9 +6,12 @@ local NP = E:GetModule("NamePlates") local modName = mod:GetName() local activeFilters, links = {}, {} -local ipairs, pairs, next = ipairs, pairs, next +local ipairs, pairs, next, unpack = ipairs, pairs, next, unpack local tremove, twipe = table.remove, table.wipe local format = string.format +local max = math.max + +local E_UIFrameFadeIn, E_UIFrameFadeOut = E.UIFrameFadeIn, E.UIFrameFadeOut local function shallowCopy(t) local copy = {} @@ -18,20 +21,84 @@ local function shallowCopy(t) return copy end +local function updateAllIcons(db, enabled) + if enabled then + for filterName, iconData in pairs(db.StyleFilterIcons.iconsData) do + for plate in pairs(NP.CreatedPlates) do + local frame = plate.UnitFrame + local icons = frame.styleIcons + if icons then + if not icons[filterName] then + icons[filterName] = CreateFrame("Frame", nil, frame) + if iconData.backdrop then + icons[filterName]:CreateBackdrop('Transparent') + end + icons[filterName].tex = icons[filterName]:CreateTexture(nil, "ARTWORK") + icons[filterName].tex:SetAllPoints() + icons[filterName].tex:SetTexCoord(unpack(E.TexCoords)) + mod:SecureHook(icons[filterName], "SetAlpha", function(icon, alpha) if alpha == 0 then icon:Hide() end end) + end + icons[filterName]:ClearAllPoints() + icons[filterName]:Size(iconData.size) + icons[filterName]:Point(iconData.point, + (frame.Health and frame.Health:IsVisible()) and frame.Health or frame.Name, + iconData.relativeTo, iconData.xOffset, iconData.yOffset) + icons[filterName]:SetFrameLevel(max(1,frame:GetFrameLevel() + iconData.level)) + icons[filterName].tex:SetTexture(iconData.tex) + icons[filterName].level = iconData.level + icons[filterName].point = iconData.point + icons[filterName].relativeTo = iconData.relativeTo + icons[filterName].xOffset = iconData.xOffset + icons[filterName].yOffset = iconData.yOffset + if icons[filterName].backdrop then + if not iconData.backdrop then + icons[filterName].backdrop:Hide() + else + icons[filterName].backdrop:Show() + end + elseif iconData.backdrop then + icons[filterName]:CreateBackdrop('Transparent') + end + end + end + end + else + for plate in pairs(NP.CreatedPlates) do + local frame = plate.UnitFrame + local icons = frame.styleIcons + if icons then + for filterName, icon in pairs(icons) do + icon:Hide() + icons[filterName] = nil + end + end + end + end +end + + P["Extras"]["nameplates"][modName] = { - ["enabled"] = false, - ["links"] = {}, - ["selectedLink"] = 1, + ["StyleFilterLinks"] = { + ["enabled"] = false, + ["links"] = {}, + ["selectedLink"] = 1, + }, + ["StyleFilterIcons"] = { + ["enabled"] = false, + ["selectedForIcon"] = "", + ["iconsData"] = {}, + }, } function mod:LoadConfig() local db = E.db.Extras.nameplates[modName] - local function selectedLink() return db.selectedLink end + local function selectedLink() return db.StyleFilterLinks.selectedLink end + local function selectedForIcon() return db.StyleFilterIcons.selectedForIcon end core.nameplates.args[modName] = { type = "group", name = L[modName], args = { - StyleFilter = { + StyleFilterLinks = { order = 1, type = "group", guiInline = true, @@ -43,34 +110,35 @@ function mod:LoadConfig() disabled = false, name = core.pluginColor..L["Enable"], desc = "", - get = function(info) return db[info[#info]] end, - set = function(info, value) db[info[#info]] = value self:Toggle(value) end, + get = function(info) return db.StyleFilterLinks[info[#info]] end, + set = function(info, value) db.StyleFilterLinks[info[#info]] = value self:Toggle(db) end, }, selectLink = { order = 1, - type = 'select', + type = "select", name = L["Select Link"], desc = "", values = function() local values = {} - for i, link in ipairs(db.links) do + for i, link in ipairs(db.StyleFilterLinks.links) do values[i] = format("%s -> %s", link.target, link.apply) end return values end, get = function() return selectedLink() end, - set = function(_, value) db.selectedLink = value end, - disabled = function() return not db.enabled or #db.links == 0 end, + set = function(_, value) db.StyleFilterLinks.selectedLink = value end, + disabled = function() return not db.StyleFilterLinks.enabled or #db.StyleFilterLinks.links == 0 end, }, }, }, settings = { + order = 2, type = "group", guiInline = true, name = L["Settings"], - get = function(info) return db[info[#info]] end, - set = function(info, value) db[info[#info]] = value self:Toggle(true) end, - disabled = function() return not db.enabled end, + get = function(info) return db.StyleFilterLinks[info[#info]] end, + set = function(info, value) db.StyleFilterLinks[info[#info]] = value self:Toggle(db) end, + disabled = function() return not db.StyleFilterLinks.enabled end, args = { newLink = { order = 1, @@ -78,9 +146,9 @@ function mod:LoadConfig() name = L["New Link"], desc = "", func = function() - local id = #db.links + 1 - db.links[id] = {target = '', apply = ''} - db.selectedLink = id + local id = #db.StyleFilterLinks.links + 1 + db.StyleFilterLinks.links[id] = {target = '', apply = ''} + db.StyleFilterLinks.selectedLink = id end, }, deleteLink = { @@ -89,11 +157,11 @@ function mod:LoadConfig() name = L["Delete Link"], desc = "", func = function() - tremove(db.links, selectedLink()) - db.selectedLink = 1 - self:Toggle(true) + tremove(db.StyleFilterLinks.links, selectedLink()) + db.StyleFilterLinks.selectedLink = 1 + self:Toggle(db) end, - disabled = function() return not db.enabled or #db.links == 0 end, + disabled = function() return not db.StyleFilterLinks.enabled or #db.StyleFilterLinks.links == 0 end, }, targetFilter = { order = 3, @@ -103,7 +171,7 @@ function mod:LoadConfig() values = function() local allFilters = core:GetUnitDropdownOptions(E.global.nameplates.filters) local usedTargets = {} - for i, link in pairs(db.links) do + for i, link in pairs(db.StyleFilterLinks.links) do if i ~= selectedLink() then usedTargets[link.target] = true end @@ -118,16 +186,16 @@ function mod:LoadConfig() return availableFilters end, get = function() - if not db.links[selectedLink()] then - db.selectedLink = #db.links + if not db.StyleFilterLinks.links[selectedLink()] then + db.StyleFilterLinks.selectedLink = #db.StyleFilterLinks.links end - return db.links[selectedLink()] and db.links[selectedLink()].target or "" + return db.StyleFilterLinks.links[selectedLink()] and db.StyleFilterLinks.links[selectedLink()].target or "" end, set = function(_, value) - db.links[selectedLink()].target = value - self:Toggle(true) + db.StyleFilterLinks.links[selectedLink()].target = value + self:Toggle(db) end, - hidden = function() return #db.links == 0 end, + hidden = function() return #db.StyleFilterLinks.links == 0 end, }, applyFilter = { order = 4, @@ -137,7 +205,7 @@ function mod:LoadConfig() values = function() local allFilters = core:GetUnitDropdownOptions(E.global.nameplates.filters) local usedTargets = {} - for _, link in pairs(db.links) do + for _, link in pairs(db.StyleFilterLinks.links) do usedTargets[link.target] = true end local availableFilters = {} @@ -149,17 +217,158 @@ function mod:LoadConfig() return availableFilters end, get = function() - if not db.links[selectedLink()] then - db.selectedLink = #db.links + if not db.StyleFilterLinks.links[selectedLink()] then + db.StyleFilterLinks.selectedLink = #db.StyleFilterLinks.links end - return db.links[selectedLink()] and db.links[selectedLink()].apply or "" + return db.StyleFilterLinks.links[selectedLink()] and db.StyleFilterLinks.links[selectedLink()].apply or "" end, set = function(_, value) - db.links[selectedLink()].apply = value - self:Toggle(true) + db.StyleFilterLinks.links[selectedLink()].apply = value + self:Toggle(db) + end, + hidden = function() return #db.StyleFilterLinks.links == 0 end, + }, + }, + }, + StyleFilterIcons = { + order = 3, + type = "group", + guiInline = true, + name = L["Style Filter Icons"], + desc = L["Custom icons for the style filter."], + get = function(info) + local data = db.StyleFilterIcons.iconsData[selectedForIcon()] + return data and data[info[#info]] + end, + set = function(info, value) + local data = db.StyleFilterIcons.iconsData[selectedForIcon()] + if data then + data[info[#info]] = value + updateAllIcons(db, true) + end + end, + args = { + enabled = { + order = 1, + type = "toggle", + disabled = false, + name = core.pluginColor..L["Enable"], + desc = "", + get = function(info) return db.StyleFilterIcons[info[#info]] end, + set = function(info, value) db.StyleFilterIcons[info[#info]] = value self:Toggle(db) end, + }, + selectedForIcon = { + order = 2, + type = "select", + name = L["Target Filter"], + desc = L["Select a filter to trigger the styling."], + values = function() + local list = {} + for filterName in pairs(core:GetUnitDropdownOptions(E.global.nameplates.filters)) do + list[filterName] = filterName + end + return list + end, + get = function(info) return db.StyleFilterIcons[info[#info]] end, + set = function(info, value) db.StyleFilterIcons[info[#info]] = value end, + disabled = function() return not db.StyleFilterIcons.enabled end, + }, + createIcon = { + order = 3, + type = "execute", + name = L["Create Icon"], + desc = "", + func = function() + db.StyleFilterIcons.iconsData[selectedForIcon()] = { + tex = "Interface\\Icons\\INV_Misc_QuestionMark", + size = 30, level = 15, + point = "BOTTOM", relativeTo = "TOP", + xOffset = 0, yOffset = 45, + } + self:Toggle(db) + end, + disabled = function() + return not E.global.nameplates.filters[selectedForIcon()] + or db.StyleFilterIcons.iconsData[selectedForIcon()] end, + hidden = function() return not db.StyleFilterIcons.enabled end, + }, + deleteIcon = { + order = 4, + type = "execute", + name = L["Delete Icon"], + desc = "", + func = function() + db.StyleFilterIcons.iconsData[selectedForIcon()] = false + db.StyleFilterIcons.selectedForIcon = "" + self:Toggle(db) end, - hidden = function() return #db.links == 0 end, + disabled = function() + return not (E.global.nameplates.filters[selectedForIcon()] + and db.StyleFilterIcons.iconsData[selectedForIcon()]) end, + hidden = function() return not db.StyleFilterIcons.enabled end, }, + backdrop = { + order = 5, + type = "toggle", + name = L["Use Backdrop"], + desc = "", + hidden = function() return not (db.StyleFilterIcons.enabled and db.StyleFilterIcons.iconsData[selectedForIcon()]) end, + }, + tex = { + order = 6, + type = "input", + name = L["Texture"], + desc = L["E.g. Interface\\Icons\\INV_Misc_QuestionMark"], + hidden = function() return not (db.StyleFilterIcons.enabled and db.StyleFilterIcons.iconsData[selectedForIcon()]) end, + }, + point = { + order = 7, + type = "select", + name = L["Point"], + desc = "", + values = E.db.Extras.pointOptions, + hidden = function() return not (db.StyleFilterIcons.enabled and db.StyleFilterIcons.iconsData[selectedForIcon()]) end, + }, + relativeTo = { + order = 8, + type = "select", + name = L["Relative Point"], + desc = "", + values = E.db.Extras.pointOptions, + hidden = function() return not (db.StyleFilterIcons.enabled and db.StyleFilterIcons.iconsData[selectedForIcon()]) end, + }, + size = { + order = 9, + type = "range", + name = L["Size"], + desc = "", + min = 4, max = 48, step = 1, + hidden = function() return not (db.StyleFilterIcons.enabled and db.StyleFilterIcons.iconsData[selectedForIcon()]) end, + }, + xOffset = { + order = 10, + type = "range", + name = L["X Offset"], + desc = "", + min = -100, max = 100, step = 1, + hidden = function() return not (db.StyleFilterIcons.enabled and db.StyleFilterIcons.iconsData[selectedForIcon()]) end, + }, + yOffset = { + order = 11, + type = "range", + name = L["Y Offset"], + desc = "", + min = -100, max = 100, step = 1, + hidden = function() return not (db.StyleFilterIcons.enabled and db.StyleFilterIcons.iconsData[selectedForIcon()]) end, + }, + level = { + order = 12, + type = "range", + name = L["Level"], + desc = "", + min = -200, max = 200, step = 1, + hidden = function() return not (db.StyleFilterIcons.enabled and db.StyleFilterIcons.iconsData[selectedForIcon()]) end, + }, }, }, }, @@ -193,17 +402,18 @@ local function recheckAllPlates() end end -function mod:StyleFilterPass(self, frame, actions, pass) + +function mod:StyleFilterPassLinks(frame, actions, pass) if pass then return end local filters = E.global.nameplates.filters - for link in pairs(links) do - if filters[link.target].actions == actions then - local apply = link.apply + for target, info in pairs(links) do + if filters[target].actions == actions then + local apply = info.apply frame.filteringOthers = frame.filteringOthers or {} - frame.filteringOthers[apply] = link.target + frame.filteringOthers[apply] = target activeFilters[apply] = activeFilters[apply] or { count = 0, frames = {} } if not activeFilters[apply].frames[frame] then @@ -216,7 +426,83 @@ function mod:StyleFilterPass(self, frame, actions, pass) end end -function mod:StyleFilterClear(self, frame, pass) +function mod:StyleFilterPassIcons(frame, actions) + local filters = E.global.nameplates.filters + + for target, info in pairs(links) do + if filters[target].actions == actions then + local icon = frame.styleIcons[target] + if info.iconData.backdrop then + local color = actions.color.border and actions.color.borderColor + if color then + icon.backdrop:SetBackdropBorderColor(color.r, color.g, color.b, color.a) + else + icon.backdrop:SetBackdropBorderColor(unpack(E.media.bordercolor)) + end + end + icon:Show() + E_UIFrameFadeIn(nil, icon, 0.1, icon:GetAlpha(), 1) + end + end +end + +function mod:StyleFilterPass(_, frame, actions, pass) + local filters = E.global.nameplates.filters + if pass then + for target, info in pairs(links) do + local iconData = info.iconData + if iconData and filters[target].actions == actions then + local icon = frame.styleIcons[target] + if iconData.backdrop then + local color = actions.color.border and actions.color.borderColor + if color then + icon.backdrop:SetBackdropBorderColor(color.r, color.g, color.b, color.a) + else + icon.backdrop:SetBackdropBorderColor(unpack(E.media.bordercolor)) + end + end + icon:Show() + E_UIFrameFadeIn(nil, icon, 0.1, icon:GetAlpha(), 1) + end + end + else + for target, info in pairs(links) do + if filters[target].actions == actions then + if info.link then + local apply = info.apply + + frame.filteringOthers = frame.filteringOthers or {} + frame.filteringOthers[apply] = target + + activeFilters[apply] = activeFilters[apply] or { count = 0, frames = {} } + if not activeFilters[apply].frames[frame] then + activeFilters[apply].frames[frame] = true + activeFilters[apply].count = activeFilters[apply].count + 1 + end + + frame.trigger = frame.trigger or (activeFilters[apply].count == 1) + end + local iconData = info.iconData + if iconData then + local icon = frame.styleIcons[target] + if iconData.backdrop then + local color = actions.color.border and actions.color.borderColor + if color then + icon.backdrop:SetBackdropBorderColor(color.r, color.g, color.b, color.a) + else + icon.backdrop:SetBackdropBorderColor(unpack(E.media.bordercolor)) + end + end + icon:Show() + E_UIFrameFadeIn(nil, icon, 0.1, icon:GetAlpha(), 1) + end + end + end + end +end + + +function mod:StyleFilterClearLinks(frame, pass) if pass then return end if frame.filteringOthers then @@ -230,12 +516,39 @@ function mod:StyleFilterClear(self, frame, pass) frame.untrigger = frame.untrigger or (activeFilters[apply].count == 0) end end - if not next(frame.filteringOthers) then frame.filteringOthers = nil end end end -function mod:StyleFilterUpdate(self, frame, event) +function mod:StyleFilterClearIcons(frame) + for _, icon in pairs(frame.styleIcons or {}) do + E_UIFrameFadeOut(nil, icon, 0.1, icon:GetAlpha(), 0) + end +end + +function mod:StyleFilterClear(_, frame, pass) + if not pass then + if frame.filteringOthers then + for apply in pairs(frame.filteringOthers) do + if activeFilters[apply] and activeFilters[apply].frames[frame] then + frame.filteringOthers[apply] = nil + + activeFilters[apply].frames[frame] = nil + activeFilters[apply].count = activeFilters[apply].count - 1 + + frame.untrigger = frame.untrigger or (activeFilters[apply].count == 0) + end + end + if not next(frame.filteringOthers) then frame.filteringOthers = nil end + end + end + for _, icon in pairs(frame.styleIcons or {}) do + E_UIFrameFadeOut(nil, icon, 0.1, icon:GetAlpha(), 0) + end +end + + +function mod:StyleFilterUpdate(self, frame, ...) if frame.OnShowHold then return end local filteringOthers, triggerState = frame.filteringOthers @@ -245,7 +558,7 @@ function mod:StyleFilterUpdate(self, frame, event) triggerState = shallowCopy(filteringOthers) end - mod.hooks[NP].StyleFilterUpdate(self, frame, event) + mod.hooks[NP].StyleFilterUpdate(self, frame, ...) if frame.trigger or frame.untrigger then local changed @@ -274,7 +587,6 @@ function mod:StyleFilterUpdate(self, frame, event) recheckAllPlates() end end - local filters = E.global.nameplates.filters for apply, info in pairs(activeFilters) do @@ -284,18 +596,73 @@ function mod:StyleFilterUpdate(self, frame, event) end end -function mod:OnShow(self, isConfig, dontHideHighlight) +function mod:Construct_HealthBar(self, frame) + frame.styleIcons = {} + local icons = frame.styleIcons + for filterName, info in pairs(links) do + local iconData = info.iconData + if iconData then + icons[filterName] = CreateFrame("Frame", nil, frame) + if iconData.backdrop then + icons[filterName]:CreateBackdrop('Transparent') + end + icons[filterName]:Hide() + icons[filterName]:Size(iconData.size) + icons[filterName].tex = icons[filterName]:CreateTexture(nil, "ARTWORK") + icons[filterName].tex:SetTexture(iconData.tex) + icons[filterName].tex:SetAllPoints() + icons[filterName].tex:SetTexCoord(unpack(E.TexCoords)) + icons[filterName].level = iconData.level + icons[filterName].point = iconData.point + icons[filterName].relativeTo = iconData.relativeTo + icons[filterName].xOffset = iconData.xOffset + icons[filterName].yOffset = iconData.yOffset + mod:SecureHook(icons[filterName], "SetAlpha", function(icon, alpha) if alpha == 0 then icon:Hide() end end) + end + end +end + +function mod:OnShowLinks(self, ...) local frame = self.UnitFrame frame.OnShowHold = true - mod.hooks[NP].OnShow(self, isConfig, dontHideHighlight) + mod.hooks[NP].OnShow(self, ...) frame.OnShowHold = false NP:StyleFilterUpdate(frame, "NAME_PLATE_UNIT_ADDED") end +function mod:OnShowIcons() + local frame = self.UnitFrame + for _, icon in pairs(self.UnitFrame.styleIcons or {}) do + icon:ClearAllPoints() + icon:Point(icon.point, + (frame.Health and frame.Health:IsVisible()) and frame.Health or frame.Name, + icon.relativeTo, icon.xOffset, icon.yOffset) + end +end + +function mod:OnShow(self, ...) + local frame = self.UnitFrame + + frame.OnShowHold = true + + mod.hooks[NP].OnShow(self, ...) + + frame.OnShowHold = false + + NP:StyleFilterUpdate(frame, "NAME_PLATE_UNIT_ADDED") + + for _, icon in pairs(self.UnitFrame.styleIcons or {}) do + icon:ClearAllPoints() + icon:Point(icon.point, + (frame.Health and frame.Health:IsVisible()) and frame.Health or frame.Name, + icon.relativeTo, icon.xOffset, icon.yOffset) + end +end + function mod:OnHide(self) local frame = self.UnitFrame @@ -308,7 +675,8 @@ function mod:OnHide(self) frame.filteringOthers = nil end -function mod:Toggle(enable) + +function mod:Toggle(db) twipe(links) twipe(activeFilters) @@ -316,38 +684,196 @@ function mod:Toggle(enable) plate.filteringOthers = nil end - if enable then - if not self:IsHooked(NP, 'OnShow') then self:RawHook(NP, 'OnShow') end - if not self:IsHooked(NP, 'OnHide') then self:SecureHook(NP, 'OnHide') end - if not self:IsHooked(NP, 'StyleFilterPass') then self:SecureHook(NP, 'StyleFilterPass') end - if not self:IsHooked(NP, 'StyleFilterClear') then self:SecureHook(NP, 'StyleFilterClear') end - if not self:IsHooked(NP, 'StyleFilterUpdate') then self:RawHook(NP, 'StyleFilterUpdate') end + local linksEnabled, iconsEnabled = db.StyleFilterLinks.enabled, db.StyleFilterIcons.enabled + if not core.reload and (linksEnabled or iconsEnabled) then + local filters = E.global.nameplates.filters + + if self:IsHooked(NP, 'StyleFilterPass') then self:Unhook(NP, 'StyleFilterPass') end + if self:IsHooked(NP, 'StyleFilterClear') then self:Unhook(NP, 'StyleFilterClear') end + if self:IsHooked(NP, 'OnShow') then self:Unhook(NP, 'OnShow') end if not self:IsHooked(NP, 'StyleFilterConfigure') then self:RawHook(NP, 'StyleFilterConfigure', function() twipe(links) twipe(activeFilters) - for i, link in ipairs(E.db.Extras.nameplates[modName].links) do - if not E.global.nameplates.filters[link.target] or not E.global.nameplates.filters[link.apply] then - tremove(E.db.Extras.nameplates[modName].links, i) - elseif E.global.nameplates.filters[link.target].triggers and E.global.nameplates.filters[link.apply].actions then - links[link] = true + filters = E.global.nameplates.filters + + if db.StyleFilterLinks.enabled then + for i = #db.StyleFilterLinks.links, 1, -1 do + local link = db.StyleFilterLinks.links[i] + if link then + local target, apply = link.target, link.apply + if not filters[target] or not filters[apply] then + tremove(db.StyleFilterLinks.links, i) + elseif filters[target].triggers and filters[apply].actions then + links[target] = { link = link, apply = apply } + end + end + end + end + if db.StyleFilterIcons.enabled then + local removed = {} + + for filterName, iconData in pairs(db.StyleFilterIcons.iconsData) do + if not filters[filterName] then + removed[filterName] = false + for plate in pairs(NP.CreatedPlates) do + local frame = plate.UnitFrame + local icons = frame.styleIcons + if icons and icons[filterName] then + icons[filterName]:Hide() + icons[filterName] = nil + end + end + else + removed[filterName] = iconData + for plate in pairs(NP.CreatedPlates) do + local frame = plate.UnitFrame + local icons = frame.styleIcons + if not icons then + frame.styleIcons = {} + icons = frame.styleIcons + end + if not icons[filterName] then + icons[filterName] = CreateFrame("Frame", nil, frame) + if iconData.backdrop then + icons[filterName]:CreateBackdrop('Transparent') + end + icons[filterName]:Size(iconData.size) + icons[filterName]:SetFrameLevel(max(1,frame:GetFrameLevel() + iconData.level)) + icons[filterName].tex = icons[filterName]:CreateTexture(nil, "ARTWORK") + icons[filterName].tex:SetTexture(iconData.tex) + icons[filterName].tex:SetTexCoord(unpack(E.TexCoords)) + icons[filterName].tex:SetAllPoints() + icons[filterName].level = iconData.level + icons[filterName].point = iconData.point + icons[filterName].relativeTo = iconData.relativeTo + icons[filterName].xOffset = iconData.xOffset + icons[filterName].yOffset = iconData.yOffset + mod:SecureHook(icons[filterName], "SetAlpha", function(icon, alpha) if alpha == 0 then icon:Hide() end end) + end + icons[filterName]:Hide() + end + end + end + for filterName, iconData in pairs(removed) do + if not iconData then + db.StyleFilterIcons.iconsData[filterName] = nil + if links[filterName] and not links[filterName].link then + links[filterName] = nil + end + elseif not links[filterName] then + links[filterName] = { iconData = iconData } + else + links[filterName].iconData = iconData + end end end - mod.hooks[NP].StyleFilterConfigure() end) end - - for _, link in pairs(E.db.Extras.nameplates[modName].links) do - if E.global.nameplates.filters[link.target] and E.global.nameplates.filters[link.apply] - and E.global.nameplates.filters[link.target].triggers and E.global.nameplates.filters[link.apply].actions then - links[link] = true + if linksEnabled then + for _, link in pairs(db.StyleFilterLinks.links) do + local target, apply = link.target, link.apply + if filters[target] and filters[apply] + and filters[target].triggers and filters[apply].actions then + links[target] = { link = link, apply = apply } + end + end + if not self:IsHooked(NP, 'OnHide') then self:SecureHook(NP, 'OnHide') end + if not self:IsHooked(NP, 'StyleFilterUpdate') then self:RawHook(NP, 'StyleFilterUpdate') end + if iconsEnabled then + self:SecureHook(NP, 'StyleFilterPass') + self:SecureHook(NP, 'StyleFilterClear') + self:RawHook(NP, 'OnShow') + else + self:SecureHook(NP, 'StyleFilterPass', self.StyleFilterPassLinks) + self:SecureHook(NP, 'StyleFilterClear', self.StyleFilterClearLinks) + self:RawHook(NP, 'OnShow', function(...) self:OnShowLinks(...) end) end end + if iconsEnabled then + local removed = {} + for filterName, iconData in pairs(db.StyleFilterIcons.iconsData) do + if not iconData then + removed[filterName] = false + for plate in pairs(NP.CreatedPlates) do + local frame = plate.UnitFrame + local icons = frame.styleIcons + if icons and icons[filterName] then + icons[filterName]:Hide() + icons[filterName] = nil + end + end + else + removed[filterName] = iconData + for plate in pairs(NP.CreatedPlates) do + local frame = plate.UnitFrame + local icons = frame.styleIcons + if not icons then + frame.styleIcons = {} + icons = frame.styleIcons + end + if not icons[filterName] then + icons[filterName] = CreateFrame("Frame", nil, frame) + if iconData.backdrop then + icons[filterName]:CreateBackdrop('Transparent') + end + icons[filterName]:Size(iconData.size) + icons[filterName]:SetFrameLevel(max(1,frame:GetFrameLevel() + iconData.level)) + icons[filterName].tex = icons[filterName]:CreateTexture(nil, "ARTWORK") + icons[filterName].tex:SetTexture(iconData.tex) + icons[filterName].tex:SetAllPoints() + icons[filterName].tex:SetTexCoord(unpack(E.TexCoords)) + mod:SecureHook(icons[filterName], "SetAlpha", function(icon, alpha) if alpha == 0 then icon:Hide() end end) + end + icons[filterName].level = iconData.level + icons[filterName].point = iconData.point + icons[filterName].relativeTo = iconData.relativeTo + icons[filterName].xOffset = iconData.xOffset + icons[filterName].yOffset = iconData.yOffset + icons[filterName]:Hide() + end + end + end + for filterName, iconData in pairs(removed) do + if not iconData then + db.StyleFilterIcons.iconsData[filterName] = nil + if links[filterName] and not links[filterName].link then + links[filterName] = nil + end + elseif not links[filterName] then + links[filterName] = { iconData = iconData } + else + links[filterName].iconData = iconData + end + end + if not self:IsHooked(NP, 'Construct_HealthBar') then self:SecureHook(NP, 'Construct_HealthBar') end + if not self:IsHooked(NP, 'ResetNameplateFrameLevel') then self:SecureHook(NP, 'ResetNameplateFrameLevel', function(self, frame) + if frame.styleIcons then + for _, icon in pairs(frame.styleIcons) do + icon:SetFrameLevel(max(1,frame:GetFrameLevel() + icon.level)) + end + end + end) + end + if not linksEnabled then + self:SecureHook(NP, 'StyleFilterPass', self.StyleFilterPassIcons) + self:SecureHook(NP, 'StyleFilterClear', self.StyleFilterClearIcons) + self:SecureHook(NP, 'OnShow', self.OnShowIcons) + end + core.plateAnchoring['styleIcons'] = function(_, frame) + return nil, {frame.styleIcons} + end + updateAllIcons(db, true) + else + updateAllIcons(db, false) + end else - for _, func in pairs({'StyleFilterPass', 'StyleFilterClear', 'StyleFilterConfigure', 'OnShow', 'StyleFilterUpdate'}) do + for _, func in pairs({'StyleFilterPass', 'StyleFilterClear', 'StyleFilterConfigure', + 'OnShow', 'StyleFilterUpdate', 'Construct_HealthBar', 'ResetNameplateFrameLevel'}) do if self:IsHooked(NP, func) then self:Unhook(NP, func) end end + updateAllIcons(db, false) end recheckAllPlates() @@ -357,7 +883,7 @@ function mod:InitializeCallback() if not E.private.nameplates.enable then return end mod:LoadConfig() - mod:Toggle(E.db.Extras.nameplates[modName].enabled) + mod:Toggle(E.db.Extras.nameplates[modName]) end core.modules[modName] = mod.InitializeCallback \ No newline at end of file diff --git a/Modules/Unitframes/AuraBars.lua b/Modules/Unitframes/AuraBars.lua index e38a781..2f9d0c9 100644 --- a/Modules/Unitframes/AuraBars.lua +++ b/Modules/Unitframes/AuraBars.lua @@ -299,7 +299,7 @@ function mod:UpdatePostUpdateAuraBars() for _, frame in ipairs(units) do local unitframeType = frame.unitframeType if db[unitframeType] then - if frame.db.aurabar.enable then + if frame.db.aurabar and frame.db.aurabar.enable then local auraBars = frame.AuraBars auraBars.gap = db[unitframeType].enabled and -frame.db.aurabar.height or (-frame.BORDER + frame.SPACING*3) @@ -328,8 +328,10 @@ end function mod:Toggle() local enable - for _, enabled in pairs(E.db.Extras.unitframes[modName].units) do - if enabled then enable = true break end + if not core.reload then + for _, enabled in pairs(E.db.Extras.unitframes[modName].units) do + if enabled then enable = true break end + end end if enable then if not self:IsHooked(UF, "Construct_AuraBars") then self:SecureHook(UF, "Construct_AuraBars", self.Construct_AuraBars) end diff --git a/Modules/Unitframes/Auras.lua b/Modules/Unitframes/Auras.lua index abb6302..393140f 100644 --- a/Modules/Unitframes/Auras.lua +++ b/Modules/Unitframes/Auras.lua @@ -66,18 +66,18 @@ function mod:LoadConfig() local db = E.db.Extras.unitframes[modName] local function selectedType() return db.Highlights.selectedType or "FRIENDLY" end local function selectedSpellorFilter() return db.Highlights.types[selectedType()].selected or "GLOBAL" end - local function getHighlightSettings(selectedType, spellOrFilter) - local db = db.Highlights.types[selectedType] + local function getHighlightSettings(selected, spellOrFilter) + local data = db.Highlights.types[selected] if spellOrFilter == "GLOBAL" then - return db.global + return data.global elseif spellOrFilter == "CURABLE" or spellOrFilter == "STEALABLE" then - return db.special + return data.special elseif type(spellOrFilter) == 'number' then - return db.spellList[spellOrFilter].useGlobal and db.global or db.spellList[spellOrFilter] - elseif db.filterList[spellOrFilter] then - return db.filterList[spellOrFilter].useGlobal and db.global or db.filterList[spellOrFilter] + return data.spellList[spellOrFilter].useGlobal and data.global or data.spellList[spellOrFilter] + elseif data.filterList[spellOrFilter] then + return data.filterList[spellOrFilter].useGlobal and data.global or data.filterList[spellOrFilter] end - return db.global + return data.global end core.unitframes.args[modName] = { type = "group", @@ -148,7 +148,7 @@ function mod:LoadConfig() order = 2, type = "select", name = L["Add Filter"], - desc = L["Aplies highlights to all auras passing the selected filter."], + desc = L["Applies highlights to all auras passing the selected filter."], values = function() local filters = {} for filterName in pairs(E.global.unitframe.aurafilters) do @@ -179,19 +179,19 @@ function mod:LoadConfig() desc = "", func = function() local selected = selectedSpellorFilter() - local db = db.Highlights.types[selectedType()] + local data = db.Highlights.types[selectedType()] if type(selected) == 'number' then - db.spellList[selected] = nil + data.spellList[selected] = nil local _, _, icon = GetSpellInfo(selected) local link = GetSpellLink(selected) icon = gsub(icon, '\124', '\124\124') local string = '\124T' .. icon .. ':16:16\124t' .. link core:print('REMOVED', string) else - db.filterList[selected] = nil + data.filterList[selected] = nil core:print('REMOVED', selected, L[" filter removed."]) end - db.selected = "GLOBAL" + data.selected = "GLOBAL" UF:Update_AllFrames() end, disabled = function() return selectedSpellorFilter() == "GLOBAL" or selectedSpellorFilter() == "CURABLE" or selectedSpellorFilter() == "STEALABLE" end, @@ -243,14 +243,14 @@ function mod:LoadConfig() desc = L["If toggled, the GLOBAL Spell or Filter entry values would be used."], get = function() local selected = selectedSpellorFilter() - local db = db.Highlights.types[selectedType()] - local target = type(selected) == 'number' and db.spellList[selected] or db.filterList[selected] + local data = db.Highlights.types[selectedType()] + local target = type(selected) == 'number' and data.spellList[selected] or data.filterList[selected] return selected == 'GLOBAL' or selected == 'CURABLE' or selected == 'STEALABLE' or target.useGlobal end, set = function(_, value) local selected = selectedSpellorFilter() - local db = db.Highlights.types[selectedType()] - local target = type(selected) == 'number' and db.spellList[selected] or db.filterList[selected] + local data = db.Highlights.types[selectedType()] + local target = type(selected) == 'number' and data.spellList[selected] or data.filterList[selected] target.useGlobal = value UF:Update_AllFrames() end, @@ -645,18 +645,18 @@ function mod:UpdateCenteredAuras(enable) end if enable then - for _, type in ipairs({'Configure_Auras', 'Configure_AuraBars', 'UpdateBuffsHeaderPosition', 'UpdateDebuffsHeaderPosition', 'UpdateBuffsPositionAndDebuffHeight', 'UpdateDebuffsPositionAndBuffHeight', 'UpdateDebuffsHeight', 'UpdateBuffsHeight'}) do - if not self:IsHooked(UF, type) then self:SecureHook(UF, type, self[type]) end + for _, func in ipairs({'Configure_Auras', 'Configure_AuraBars', 'UpdateBuffsHeaderPosition', 'UpdateDebuffsHeaderPosition', 'UpdateBuffsPositionAndDebuffHeight', 'UpdateDebuffsPositionAndBuffHeight', 'UpdateDebuffsHeight', 'UpdateBuffsHeight'}) do + if not self:IsHooked(UF, func) then self:SecureHook(UF, func, self[func]) end end - for _, type in ipairs({'Update_PlayerFrame', 'Update_TargetFrame', 'Update_FocusFrame', 'Update_PetFrame'}) do - if not self:IsHooked(UF, type) then self:SecureHook(UF, type, self.UpdateFrame) end + for _, func in ipairs({'Update_PlayerFrame', 'Update_TargetFrame', 'Update_FocusFrame', 'Update_PetFrame'}) do + if not self:IsHooked(UF, func) then self:SecureHook(UF, func, self.UpdateFrame) end end else - for _, type in ipairs({'Configure_Auras', 'Configure_AuraBars', 'UpdateBuffsHeaderPosition', 'UpdateDebuffsHeaderPosition', 'UpdateBuffsPositionAndDebuffHeight', 'UpdateDebuffsPositionAndBuffHeight', 'UpdateDebuffsHeight', 'UpdateBuffsHeight'}) do - if self:IsHooked(UF, type) then self:Unhook(UF, type) end + for _, func in ipairs({'Configure_Auras', 'Configure_AuraBars', 'UpdateBuffsHeaderPosition', 'UpdateDebuffsHeaderPosition', 'UpdateBuffsPositionAndDebuffHeight', 'UpdateDebuffsPositionAndBuffHeight', 'UpdateDebuffsHeight', 'UpdateBuffsHeight'}) do + if self:IsHooked(UF, func) then self:Unhook(UF, func) end end - for _, type in ipairs({'Update_PlayerFrame', 'Update_TargetFrame', 'Update_FocusFrame', 'Update_PetFrame'}) do - if self:IsHooked(UF, type) then self:Unhook(UF, type) end + for _, func in ipairs({'Update_PlayerFrame', 'Update_TargetFrame', 'Update_FocusFrame', 'Update_PetFrame'}) do + if self:IsHooked(UF, func) then self:Unhook(UF, func) end end end end @@ -846,15 +846,17 @@ function mod:Toggle() self:UpdateCenteredAuras(E.db.Extras.unitframes[modName].CenteredAuras.enabled) self:UpdateClickCancel(E.db.Extras.unitframes[modName].ClickCancel.enabled) local enabled = false - for _, type in pairs({'TypeBorders', 'SaturatedDebuffs'}) do - if E.db.Extras.unitframes[modName][type].enabled then - enabled = true - break + if not core.reload then + for _, subMod in pairs({'TypeBorders', 'SaturatedDebuffs'}) do + if E.db.Extras.unitframes[modName][subMod].enabled then + enabled = true + break + end end - end - if not enabled then - for _, info in pairs(E.db.Extras.unitframes[modName].Highlights.types) do - if info.enabled then enabled = true break end + if not enabled then + for _, info in pairs(E.db.Extras.unitframes[modName].Highlights.types) do + if info.enabled then enabled = true break end + end end end self:UpdatePostUpdateAura(enabled) diff --git a/Modules/Unitframes/ClassificationIndicator.lua b/Modules/Unitframes/ClassificationIndicator.lua index 59423ff..9d2ad53 100644 --- a/Modules/Unitframes/ClassificationIndicator.lua +++ b/Modules/Unitframes/ClassificationIndicator.lua @@ -198,7 +198,7 @@ function mod:LoadConfig() order = 9, type = "toggle", name = L["Color by Type"], - desc = L["Color enemy npc icon based on the unit type."], + desc = L["Color enemy NPC icon based on the unit type."], hidden = function() local type = selectedUnitData().selectedEnemyType return type ~= lower(type) end, }, texListSelector = { @@ -524,7 +524,7 @@ local function manageIndicators() local db = E.db.Extras.unitframes[modName].units for _, frame in ipairs(units) do local unitframeType = frame.unitframeType - if db[unitframeType] and db[unitframeType].enabled then + if not core.reload and db[unitframeType] and db[unitframeType].enabled then manageClassificationIndicator(frame, unitframeType) mod:UpdateElement(frame, frame.unit, db[unitframeType]) elseif frame.classificationIndicator then diff --git a/Modules/Unitframes/ColorFilter.lua b/Modules/Unitframes/ColorFilter.lua index ee32272..59de481 100644 --- a/Modules/Unitframes/ColorFilter.lua +++ b/Modules/Unitframes/ColorFilter.lua @@ -2,38 +2,24 @@ local E, L, _, P = unpack(ElvUI) local core = E:GetModule("Extras") local mod = core:NewModule("ColorFilter", "AceHook-3.0", "AceEvent-3.0") local UF = E:GetModule("UnitFrames") +local LSM = E.Libs.LSM local modName = mod:GetName() local metaFrame = CreateFrame("Frame") local metaTable = { units = {}, statusbars = {}, events = {} } local updatePending = false -local _G, pairs, ipairs, tonumber, tostring, unpack, loadstring, type, pcall = _G, pairs, ipairs, tonumber, tostring, unpack, loadstring, type, pcall -local find, gsub, match, sub, upper, lower, format = string.find, string.gsub, string.match, string.sub, string.upper, string.lower, string.format +mod.metaTable = metaTable +mod.metaFrame = metaFrame + +local pairs, ipairs, tonumber, tostring, unpack, loadstring, pcall = pairs, ipairs, tonumber, tostring, unpack, loadstring, pcall +local find, gsub, match, gmatch, upper, lower, format = string.find, string.gsub, string.match, string.gmatch, string.upper, string.lower, string.format local tinsert, twipe, tremove = table.insert, table.wipe, table.remove local GetNumPartyMembers, GetNumRaidMembers = GetNumPartyMembers, GetNumRaidMembers -local InCombatLockdown, GetTime = InCombatLockdown, GetTime +local InCombatLockdown, GetTime, CopyTable = InCombatLockdown, GetTime, CopyTable local E_Delay = E.Delay -local function compare(value, operator, target) - if operator == '>' then - return value > target - elseif operator == '<' then - return value < target - elseif operator == '=' then - return value == target - elseif operator == '~=' then - return value ~= target - elseif operator == '<=' then - return value <= target - elseif operator == '>=' then - return value >= target - else - return false - end -end - local function toggleHook(target, hook, extension) if hook then if not mod:IsHooked(UF, target) then @@ -163,6 +149,24 @@ local function calculateAdaptWeight(overrideH, overrideP, adaptPriority, threatB return result end +local function statusCheck(unit, statusbar, tabIndex) + for _, frame in pairs(metaTable.units[unit] or {}) do + if frame.colorFilter[statusbar].appliedColorTabIndex == tabIndex then + return true + end + end +end + +local function countCheck(unit, statusbar, tabIndex) + local count = 0 + for _, frame in pairs(metaTable.units[unit] or {}) do + if frame.colorFilter[statusbar].appliedColorTabIndex == tabIndex then + count = count + 1 + end + end + return count +end + P["Extras"]["unitframes"][modName] = { ["selectedUnit"] = 'player', @@ -187,6 +191,8 @@ P["Extras"]["unitframes"][modName] = { ["conditions"] = "", ["colors"] = {1, 1, 1}, ["enableColors"] = false, + ["texture"] = "", + ["enableTexture"] = false, ["flash"] = { ["enabled"] = false, ["colors"] = {1, 1, 1, 1}, @@ -527,7 +533,7 @@ function mod:LoadConfig() width = "double", disabled = function() return greyed() end, name = core.pluginColor..L["Enable"], - desc = L["Toggle color flash for the current tab."], + desc = "", }, colors = { order = 2, @@ -677,7 +683,7 @@ function mod:LoadConfig() name = core.pluginColor..L["Enable"], desc = L["Toggle classbar borders."], hidden = function() - return customFrames[selectedUnit()] + return selectedBar() == 'Castbar' or customFrames[selectedUnit()] or not (selectedUFData().classbar and selectedUFData().classbar.enable) or not selectedTabData().highlight.borders.enabled end, disabled = function() return greyed() or not selectedUFData().classbar.enable end, @@ -688,7 +694,7 @@ function mod:LoadConfig() name = core.pluginColor..L["Enable"], desc = L["Toggle infopanel borders."], hidden = function() - return customFrames[selectedUnit()] + return selectedBar() == 'Castbar' or customFrames[selectedUnit()] or not (selectedUFData().infoPanel and selectedUFData().infoPanel.enable) or not selectedTabData().highlight.borders.enabled end, disabled = function() @@ -702,7 +708,7 @@ function mod:LoadConfig() get = function() return unpack(selectedTabData().highlight.borders.classBarBorderColors) end, set = function(_, r, g, b) selectedTabData().highlight.borders.classBarBorderColors = {r, g, b} self:Toggle() end, hidden = function() - return customFrames[selectedUnit()] + return selectedBar() == 'Castbar' or customFrames[selectedUnit()] or not (selectedUFData().classbar and selectedUFData().classbar.enable) or not selectedTabData().highlight.borders.enabled end, disabled = function() @@ -717,7 +723,7 @@ function mod:LoadConfig() get = function() return unpack(selectedTabData().highlight.borders.infoPanelBorderColors) end, set = function(_, r, g, b) selectedTabData().highlight.borders.infoPanelBorderColors = {r, g, b} self:Toggle() end, hidden = function() - return customFrames[selectedUnit()] + return selectedBar() == 'Castbar' or customFrames[selectedUnit()] or not (selectedUFData().infoPanel and selectedUFData().infoPanel.enable) or not selectedTabData().highlight.borders.enabled end, disabled = function() @@ -729,7 +735,7 @@ function mod:LoadConfig() order = 7, type = "select", name = L["ClassBar Adapt To"], - desc = L["Copies color of the selected bar."], + desc = L["Copies the color of the selected bar."], get = function() return selectedUnitData().classBarBorderAdapt end, set = function(_, value) selectedUnitData().classBarBorderAdapt = value self:Toggle() end, values = { @@ -737,7 +743,8 @@ function mod:LoadConfig() ["Power"] = L["Power"], ["NONE"] = L["None"], }, - hidden = function() return not selectedTabData().highlight.borders.enabled end, + hidden = function() return selectedBar() == 'Castbar' + or not selectedTabData().highlight.borders.enabled end, disabled = function() return greyed() or not (selectedUFData().classbar and selectedUFData().classbar.enable) end, @@ -746,7 +753,7 @@ function mod:LoadConfig() order = 8, type = "select", name = L["InfoPanel Adapt To"], - desc = L["Copies color of the selected bar."], + desc = L["Copies the color of the selected bar."], get = function() return selectedUnitData().infoPanelBorderAdapt end, set = function(_, value) selectedUnitData().infoPanelBorderAdapt = value self:Toggle() end, values = { @@ -755,7 +762,8 @@ function mod:LoadConfig() ["NONE"] = L["None"], }, hidden = function() - return customFrames[selectedUnit()] or not selectedTabData().highlight.borders.enabled end, + return selectedBar() == 'Castbar' + or customFrames[selectedUnit()] or not selectedTabData().highlight.borders.enabled end, disabled = function() return greyed() or not (selectedUFData().infoPanel and selectedUFData().infoPanel.enable) end, }, @@ -770,7 +778,8 @@ function mod:LoadConfig() ["THREAT"] = L["Threat"], }, hidden = function() - return customFrames[selectedUnit()] or not selectedTabData().highlight.borders.enabled end, + return selectedBar() == 'Castbar' + or customFrames[selectedUnit()] or not selectedTabData().highlight.borders.enabled end, }, bordersPriority = { order = 11, @@ -785,9 +794,10 @@ function mod:LoadConfig() ["NONE"] = L["Bar-specific"], }, hidden = function() - return customFrames[selectedUnit()] or not selectedTabData().highlight.borders.enabled end, + return selectedBar() == 'Castbar' + or customFrames[selectedUnit()] or not selectedTabData().highlight.borders.enabled end, disabled = function() - return greyed() or selectedBar() == 'Castbar' + return greyed() or find(selectedUnit(),'assist') or find(selectedUnit(),'tank') or (selectedUFData().power and selectedUFData().power.detachFromFrame) end, }, @@ -796,7 +806,7 @@ function mod:LoadConfig() colors = { order = 10, type = "group", - name = L["Colors"], + name = L["Color"], guiInline = true, get = function(info) return selectedUnitData()[info[#info]] end, set = function(info, value) selectedUnitData()[info[#info]] = value self:Toggle() end, @@ -806,7 +816,7 @@ function mod:LoadConfig() order = 1, type = "toggle", name = core.pluginColor..L["Enable"], - desc = L["Toggle bar coloring."], + desc = "", get = function(info) return selectedTabData()[info[#info]] end, set = function(info, value) selectedTabData()[info[#info]] = value self:Toggle() end, }, @@ -821,9 +831,39 @@ function mod:LoadConfig() }, }, }, - luaSection = { + texture = { order = 11, type = "group", + name = L["Texture"], + guiInline = true, + get = function(info) return selectedUnitData()[info[#info]] end, + set = function(info, value) selectedUnitData()[info[#info]] = value self:Toggle() end, + disabled = function() return greyed() end, + args = { + enableTexture = { + order = 1, + type = "toggle", + name = core.pluginColor..L["Enable"], + desc = "", + get = function(info) return selectedTabData()[info[#info]] end, + set = function(info, value) selectedTabData()[info[#info]] = value self:Toggle() end, + }, + texture = { + order = 2, + type = "select", + name = L["Texture"], + desc = "", + dialogControl = "LSM30_Statusbar", + get = function(info) return selectedTabData()[info[#info]] end, + set = function(info, value) selectedTabData()[info[#info]] = value self:Toggle() end, + values = function() return AceGUIWidgetLSMlists.statusbar end, + disabled = function() return greyed() or not selectedTabData().enableTexture end, + }, + }, + }, + luaSection = { + order = 12, + type = "group", name = L["Lua Section"], guiInline = true, get = function(info) return selectedTabData()[info[#info]] or "" end, @@ -854,19 +894,24 @@ function mod:LoadConfig() width = "double", name = L["Conditions"], desc = L["Usage example:".. - "\n\nif UnitBuff('player', 'Stealth') or @@[player, Power, 3]@@ then".. - "\nlocal r, g, b = ElvUF_Target.Health:GetStatusBarColor() return true, {mR = r, mG = g, mB = b} end".. - "\nif UnitIsUnit(@unit, 'target') then return true end".. - "\n\n@@[raid, Health, 2, >5]@@ - returns true/false based on whether the tab in question (in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not (mentioning the same unit/group is disabled; isn't recursive)".. - "\n(>/>=/<=/5]@@ - returns true/false based on whether the tab in question ".. + "(in the example above: 'player' - target unit; 'Power' - target statusbar; '3' - target tab) is active or not".. + "\n(>/>=/<=/]*)%s*([%d]+))') - - if unit and statusbar and tabIndex then - local ogunit = unit - unit = lower(gsub(unit, '[%d]+', '')) - statusbar = gsub(statusbar, "(%a)([%w_']*)", function(first, rest) - return upper(first) .. lower(rest) - end) - tabIndex = tonumber(tabIndex) - - local result - if metaTable.units[unit] and metaTable.statusbars[unit][statusbar] then - for _, frame in pairs(metaTable.units[unit]) do - if frame:IsShown() and frame.colorFilter[statusbar].appliedColorTabIndex == tabIndex then - triggerCount = triggerCount + 1 - result = true - end - end - end - - if triggerCountStr and tonumber(triggerCountStr) then - result = result and compare(triggerCount, operator, tonumber(triggerCountStr)) - end - - -- assign true/false based on whether the respected tab conditions are applied - conditions = gsub(conditions, '@@%[.-%]@@', (result and (statusbarToUpd ~= statusbar or ogunit ~= mentionedByUnit)) and 'true' or 'false', 1) - - frame.colorFilter[statusbarToUpd].mentionedTab = tabIndex - else - core:print('FORMATTING', L["Color Filter"]) - break - end - end - - return conditions -end - -function mod:SortMentions(db, frame, conditions, mentionedByUnit, statusbarToUpd, mentionedByTabIndex) - while match(conditions, '@@%[.-%]@@') do - local tabsStateCondition = match(conditions, '@@%[(.-)%]@@') - local unit, statusbar, tabIndex = match(tabsStateCondition, '([^,%s]+),%s*([^,%s]+),%s*([%d]+)') +function mod:SortMentions(frame, conditions, mentionedByUnit, statusbarToUpd) + for tabsStateCondition in gmatch(conditions, '@@%[(.-)%]@@') do + local _, endPos, unit, statusbar, tabIndex = find(tabsStateCondition, '([^,%s]+),%s*([^,%s]+),%s*([%d]+)') + local _, _, operator, triggerCount = find(tabsStateCondition, ',%s*([~=<>]*)%s*([%d]+)', endPos) if unit and statusbar and tabIndex then unit = lower(unit) @@ -1080,33 +1025,31 @@ function mod:SortMentions(db, frame, conditions, mentionedByUnit, statusbarToUpd end) tabIndex = tonumber(tabIndex) - if metaTable.units[unit] and metaTable.statusbars[unit][statusbar] then - for _, mentionedFrame in pairs(metaTable.units[unit]) do - if not mentionedFrame.colorFilter[statusbar].mentions then - mentionedFrame.colorFilter[statusbar].mentions = {} - end - - local mentionInfo = { frame = frame:GetName(), statusbar = statusbarToUpd, unit = mentionedByUnit, tabs = db.units[mentionedByUnit].statusbars[statusbarToUpd].tabs, tabIndex = tabIndex } - - -- check if an entry with the matching mentionedByTabIndex already exists - local entryExists = false - for _, existingInfo in pairs(mentionedFrame.colorFilter[statusbar].mentions) do - if existingInfo.tabIndex == mentionedByTabIndex then - entryExists = true - end - end - if not entryExists and unit ~= mentionedByUnit then - tinsert(mentionedFrame.colorFilter[statusbar].mentions, mentionInfo) - end + local mentions = {} + for _, info in ipairs(frame.colorFilter[statusbar].mentions or {}) do + mentions[info.frame] = mentions[info.frame] or {} + mentions[info.frame][info.unit..info.statusbar..info.tabIndex] = true + end + for _, mentionedFrame in pairs(metaTable.units[unit] or {}) do + if not mentions[mentionedFrame] or not mentions[mentionedFrame][unit..statusbar..tabIndex] then + mentionedFrame.colorFilter[statusbar].mentions = mentionedFrame.colorFilter[statusbar].mentions or {} + tinsert(mentionedFrame.colorFilter[statusbar].mentions, + { frame = frame, + statusbar = statusbarToUpd, + unit = mentionedByUnit, + tabIndex = tabIndex + }) end end - - conditions = gsub(conditions, '@@%[.-%]@@', '', 1) + conditions = gsub(conditions, '@@%[.-%]@@', + triggerCount and format('(countCheck("%s", "%s", %d) %s %d)', unit, statusbar, tabIndex, operator, triggerCount) + or format('statusCheck("%s", "%s", %d)', unit, statusbar, tabIndex), 1) else core:print('FORMATTING', L["Color Filter"]) - break + return end end + return conditions end @@ -1195,7 +1138,7 @@ function mod:UpdateBorders(frame, colors, statusbar, unit, showBorders, highligh if statusbar == 'Castbar' then frame.Castbar.backdrop:SetBackdropBorderColor(r, g, b) if borders.castbarIcon then - frame.Castbar.Icon.bg.backdrop:SetBackdropBorderColor(r, g, b) + frame.Castbar.ButtonIcon.bg:SetBackdropBorderColor(r, g, b) end return end @@ -1277,7 +1220,7 @@ function mod:UpdateBorders(frame, colors, statusbar, unit, showBorders, highligh local r, g, b = unpack(E.media.unitframeBorderColor) frame.Castbar.backdrop:SetBackdropBorderColor(r, g, b) if highlight.borders.castbarIcon then - frame.Castbar.Icon.bg.backdrop:SetBackdropBorderColor(r, g, b) + frame.Castbar.ButtonIcon.bg:SetBackdropBorderColor(r, g, b) end else local weights = calculateWeight(appliedBorders.Health.override, @@ -1343,7 +1286,6 @@ function mod:UpdateBorders(frame, colors, statusbar, unit, showBorders, highligh power and appliedBorders.Power.override, adapt, threatBorders, true) - --if highlight and highlight.borders.infoPanelBorderEnabled then if showBorders then if adapt ~= 'NONE' then local appliedBordersAdapt = appliedBorders[adapt] @@ -1401,7 +1343,6 @@ function mod:UpdateBorders(frame, colors, statusbar, unit, showBorders, highligh power and appliedBorders.Power.override, adapt, threatBorders) - --if highlight and highlight.borders.classBarBorderEnabled then if showBorders then if adapt ~= 'NONE' then local appliedBordersAdapt = appliedBorders[adapt] @@ -1458,22 +1399,11 @@ end function mod:UpdateMentions(bar) for _, mentionInfo in pairs(bar.mentions) do - local frame, statusbar, unit = _G[mentionInfo.frame], mentionInfo.statusbar, mentionInfo.unit - local tabs, tabIndex = mentionInfo.tabs, mentionInfo.tabIndex + local frame, statusbar, tabIndex = mentionInfo.frame, mentionInfo.statusbar, mentionInfo.tabIndex local targetBar = frame.colorFilter[statusbar] - if (bar.appliedColorTabIndex == tabIndex - or (bar.appliedColorTabIndex ~= tabIndex and targetBar.appliedColorTabIndex == tabIndex) - or not targetBar.appliedColorTabIndex) then - self:ParseTabs(frame, statusbar, unit, tabs, nil, true) - - if not targetBar.colorApplied then - frame[statusbar]:ForceUpdate() - local flashTexture = targetBar.flashTexture - if flashTexture:IsShown() then - flashTexture.anim:Stop() - flashTexture:Hide() - end - end + if (bar.appliedColorTabIndex == tabIndex and targetBar.appliedColorTabIndex ~= tabIndex) + or (bar.appliedColorTabIndex ~= tabIndex and targetBar.appliedColorTabIndex == tabIndex) and frame[statusbar]:IsShown() then + frame[statusbar]:ForceUpdate() end end end @@ -1510,7 +1440,7 @@ function mod:UpdateThreat(unit, status) for statusbar, tabInfo in pairs(colorFilter.appliedBordersColors) do if tabInfo.override and statusbar ~= 'Castbar' then colorFilter.appliedBordersColors[statusbar].applied = false - mod:UpdateBorders(frame, tabInfo.color, statusbar, unit, true, tabInfo.highlight) + mod:UpdateBorders(frame, tabInfo.color, statusbar, unitframeType, true, tabInfo.highlight) end end end @@ -1518,20 +1448,10 @@ function mod:UpdateThreat(unit, status) colorFilter.threatBordersActive = false -- roll parser again, cause the conditions have changed by the time threat goes down if metaTable.statusbars[unitframeType] then - for statusbar, bar in pairs(metaTable.statusbars[unitframeType]) do - local targetBar = colorFilter[statusbar] + for statusbar in pairs(metaTable.statusbars[unitframeType]) do local parentBar = frame[statusbar] if parentBar and parentBar:IsShown() then - mod:ParseTabs(frame, statusbar, unit, bar.tabs) - - if not targetBar.colorApplied then - parentBar:ForceUpdate() - local flashTexture = targetBar.flashTexture - if flashTexture:IsShown() then - flashTexture.anim:Stop() - flashTexture:Hide() - end - end + parentBar:ForceUpdate() end end end @@ -1540,118 +1460,100 @@ function mod:UpdateThreat(unit, status) end -function mod:LoadConditions(frame, statusbar, unit, tab) - local conditions = tab.conditions or tab - conditions = conditions:gsub('@unit', "'"..unit.."'") - - -- check tabs state - local tabsStateBlock = match(conditions, '@@%[.-%]@@') - if tabsStateBlock then - conditions = self:SortTabsState(frame, conditions, unit, statusbar) - end - - local luaFunction, errorMsg = loadstring(conditions) - if not luaFunction then - core:print('LUA', L["Color Filter"], errorMsg) - return - end - - local success, result = pcall(luaFunction) - if not success then - core:print('FAIL', L["Color Filter"], result) - return - end - - local colors - if type(result) == "table" then - colors = result - end - - return result, colors -end - -function mod:ParseTabs(frame, statusbar, unit, tabs, isPostUpdate, skipMentions) +function mod:ParseTabs(frame, statusbar, unit, tabs, isPostUpdate) local targetBar = frame.colorFilter[statusbar] for tabIndex, tab in ipairs(tabs) do -- if colored already, do not check tabs with lower priority if targetBar.appliedColorTabIndex and tabIndex > targetBar.appliedColorTabIndex then break end - if tab.enabled then - local result, colors = self:LoadConditions(frame, statusbar, unit, tab) - if result then - -- no retriggering please - local flash = tab.flash - local flashTexture = targetBar.flashTexture - if flash.enabled and (not colors or colors.f ~= false) then - local flashColors = flash.colors - local r, g, b = flashColors[1], flashColors[2], flashColors[3] - if colors then - r, g, b = colors.fR and colors.fR or r, colors.fG and colors.fG or g, colors.fB and colors.fB or b - end - flashTexture:SetVertexColor(r, g, b) - flashTexture:Show() - - local anim = flashTexture.anim - local IsPlaying = anim and anim:IsPlaying() - if (not anim or not IsPlaying) then - if IsPlaying then anim:Stop() end - anim.fadein:SetDuration(flash.speed) - anim.fadeout:SetDuration(flash.speed) - anim:Play() - end - elseif flashTexture and flashTexture:IsShown() then - local anim = flashTexture.anim - if anim:IsPlaying() then anim:Stop() end - flashTexture:Hide() - end - - local tabColors = tab.colors - local r, g, b = tabColors[1], tabColors[2], tabColors[3] - + local result, colors = tab.conditionsFunc(frame, unit, statusCheck, countCheck) + if result then + -- no retriggering please + local flash = tab.flash + local flashTexture = targetBar.flashTexture + if flash.enabled and (not colors or colors.f ~= false) then + local flashColors = flash.colors + local r, g, b = flashColors[1], flashColors[2], flashColors[3] if colors then - r, g, b = colors.mR and colors.mR or r, colors.mG and colors.mG or g, colors.mB and colors.mB or b + r, g, b = colors.fR and colors.fR or r, colors.fG and colors.fG or g, colors.fB and colors.fB or b end + flashTexture:SetVertexColor(r, g, b) + flashTexture:Show() + + local anim = flashTexture.anim + anim.fadein:SetDuration(flash.speed) + anim.fadeout:SetDuration(flash.speed) + anim:Play() + elseif flashTexture and flashTexture:IsShown() then + flashTexture.anim:Stop() + flashTexture:Hide() + end - if tab.enableColors then - if not colors or colors.m ~= false then - frame[statusbar]:SetStatusBarColor(r, g, b) - elseif not isPostUpdate then - frame[statusbar]:ForceUpdate() - end - end + local tabColors = tab.colors + local r, g, b = tabColors[1], tabColors[2], tabColors[3] - -- store the current tab index - targetBar.colorApplied = true - targetBar.appliedColorTabIndex = tabIndex - targetBar.lastUpdate = GetTime() + if colors then + r, g, b = colors.mR and colors.mR or r, colors.mG and colors.mG or g, colors.mB and colors.mB or b + end - local highlight = tab.highlight - if highlight.glow.enabled then - self:UpdateGlow(frame, colors, statusbar, unit, true, highlight) + if tab.enableColors then + if not colors or colors.m ~= false then + frame[statusbar]:SetStatusBarColor(r, g, b) + elseif not isPostUpdate then + frame[statusbar]:ForceUpdate() end - if highlight.borders.enabled then - self:UpdateBorders(frame, colors, statusbar, unit, true, highlight) + end + if tab.enableTexture then + if not colors then + frame[statusbar]:SetStatusBarTexture(tab.fetchedTexture) + elseif colors.mT then + frame[statusbar]:SetStatusBarTexture(colors.mT) + elseif not isPostUpdate then + frame[statusbar]:SetStatusBarTexture(LSM:Fetch("statusbar", UF.db.statusbar)) end + end - if not skipMentions and targetBar.mentions then - self:UpdateMentions(targetBar) - end - elseif targetBar.appliedColorTabIndex and tabIndex == targetBar.appliedColorTabIndex then - -- conditions from the tab currently coloring the bar are no longer true, revert - targetBar.colorApplied = false - targetBar.appliedColorTabIndex = nil + -- store the current tab index + targetBar.colorApplied = true + targetBar.appliedColorTabIndex = tabIndex + targetBar.lastUpdate = GetTime() - local highlight = tab.highlight - if highlight.glow.enabled then - self:UpdateGlow(frame, nil, statusbar, unit, false) - end - if highlight.borders.enabled then - self:UpdateBorders(frame, nil, statusbar, unit, false) - end + local highlight = tab.highlight + if highlight.glow.enabled then + self:UpdateGlow(frame, colors, statusbar, frame.unitframeType, true, highlight) + end + if highlight.borders.enabled then + self:UpdateBorders(frame, colors, statusbar, frame.unitframeType, true, highlight) + end - if not skipMentions and targetBar.mentions then - self:UpdateMentions(targetBar) - end + if targetBar.mentions then + self:UpdateMentions(targetBar) + end + elseif targetBar.appliedColorTabIndex and tabIndex == targetBar.appliedColorTabIndex then + -- conditions from the tab currently coloring the bar are no longer true, revert + targetBar.colorApplied = false + targetBar.appliedColorTabIndex = nil + + local highlight = tab.highlight + if highlight.glow.enabled then + self:UpdateGlow(frame, nil, statusbar, frame.unitframeType, false) + end + if highlight.borders.enabled then + self:UpdateBorders(frame, nil, statusbar, frame.unitframeType, false) + end + + if targetBar.mentions then + self:UpdateMentions(targetBar) + end + + if tab.enableTexture then + frame[statusbar]:SetStatusBarTexture(LSM:Fetch("statusbar", UF.db.statusbar)) + end + + local flashTexture = targetBar.flashTexture + if flashTexture:IsShown() then + flashTexture.anim:Stop() + flashTexture:Hide() end end end @@ -1669,20 +1571,9 @@ function mod:PostUpdateHealthColor() local colorFilter = frame.colorFilter if not colorFilter then return end - local unit = frame.unitframeType - - local unitInfo = metaTable.statusbars[unit] + local unitInfo = metaTable.statusbars[frame.unitframeType] if unitInfo and unitInfo.Health and frame:IsShown() then mod:ParseTabs(frame, 'Health', frame.unit, unitInfo.Health.tabs, true) - - local targetBar = colorFilter['Health'] - if not targetBar.colorApplied then - local flashTexture = targetBar.flashTexture - if flashTexture:IsShown() then - flashTexture.anim:Stop() - flashTexture:Hide() - end - end end end @@ -1691,21 +1582,9 @@ function mod:PostUpdatePowerColor() local colorFilter = frame.colorFilter if not (colorFilter and colorFilter.Power) then return end - local parent = self.origParent or self:GetParent() - local unit = parent.unitframeType - - local unitInfo = metaTable.statusbars[unit] + local unitInfo = metaTable.statusbars[(self.origParent or self:GetParent()).unitframeType] if unitInfo and unitInfo.Power and frame:IsShown() then mod:ParseTabs(frame, 'Power', frame.unit, unitInfo.Power.tabs, true) - - local targetBar = colorFilter['Power'] - if not targetBar.colorApplied then - local flashTexture = targetBar.flashTexture - if flashTexture:IsShown() then - flashTexture.anim:Stop() - flashTexture:Hide() - end - end end end @@ -1714,21 +1593,9 @@ function mod:CastOnupdate() local colorFilter = frame.colorFilter if not (colorFilter and colorFilter.Castbar) then return end - local unit = frame.unitframeType - - local unitInfo = metaTable.statusbars[unit] + local unitInfo = metaTable.statusbars[frame.unitframeType] if unitInfo and unitInfo.Castbar and frame:IsShown() then mod:ParseTabs(frame, 'Castbar', frame.unit, unitInfo.Castbar.tabs, true) - - local targetBar = colorFilter['Castbar'] - if not targetBar.colorApplied then - frame.Castbar:ForceUpdate() - local flashTexture = targetBar.flashTexture - if flashTexture:IsShown() then - flashTexture.anim:Stop() - flashTexture:Hide() - end - end end end @@ -1737,20 +1604,9 @@ function mod:PostCastStart() local colorFilter = frame.colorFilter if not (colorFilter and colorFilter.Castbar) then return end - local unit = frame.unitframeType - - local unitInfo = metaTable.statusbars[unit] + local unitInfo = metaTable.statusbars[frame.unitframeType] if unitInfo and unitInfo.Castbar and frame:IsShown() then mod:ParseTabs(frame, 'Castbar', frame.unit, unitInfo.Castbar.tabs, true) - - local targetBar = colorFilter['Castbar'] - if not targetBar.colorApplied then - local flashTexture = targetBar.flashTexture - if flashTexture:IsShown() then - flashTexture.anim:Stop() - flashTexture:Hide() - end - end end end @@ -1759,14 +1615,11 @@ function mod:PostCastStop() local colorFilter = frame.colorFilter if not (colorFilter and colorFilter.Castbar) then return end - local unit = frame.unitframeType - colorFilter = colorFilter.Castbar - - local unitInfo = metaTable.statusbars[unit] + local unitInfo = metaTable.statusbars[frame.unitframeType] if unitInfo and unitInfo.Castbar then + colorFilter = colorFilter.Castbar if colorFilter.mentions then - colorFilter.appliedColorTabIndex = nil - mod:UpdateMentions(colorFilter) + mod:ParseTabs(frame, 'Castbar', frame.unit, unitInfo.Castbar.tabs, true) end end end @@ -1780,97 +1633,82 @@ function mod:Construct_Castbar(frame) end -function mod:InitAndUpdateColorFilter() - if not updatePending then - updatePending = true - E_Delay(nil, 0.1, function() - local db = E.db.Extras.unitframes[modName] - - self:SetupUnits() - - for _, unitsCluster in pairs(metaTable.units) do - for _, frame in ipairs(unitsCluster) do - self:ConstructHighlight(frame) - end - end - - for unit, unitsCluster in pairs(metaTable.units) do - if not metaFrame[unit] then - metaFrame[unit] = CreateFrame("Frame") - end - for _, frame in ipairs(unitsCluster) do - for statusbar, bar in pairs(db.units[unit].statusbars) do - local targetBar = frame.colorFilter[statusbar] - local unitInfo = metaTable.statusbars[unit][statusbar] - if bar.enabled and targetBar then - if not unitInfo then - metaTable.statusbars[unit][statusbar] = bar - - if find(bar.events, '%S+') then - self:SortEvents(bar, statusbar, unit) - end - end - - frame[statusbar]:ForceUpdate() +local function update(self) + local db = E.db.Extras.unitframes[modName] - updateHooks(frame, bar.enabled, statusbar) - elseif unitInfo then - metaTable.statusbars[unit][statusbar] = nil - end + -- shutdown the highlights + for unit, unitsCluster in pairs(metaTable.units) do + for _, frame in pairs(unitsCluster) do + if frame.colorFilter then + local colorFilter = frame.colorFilter + for statusbar in pairs(metaTable.statusbars[unit]) do + self:UpdateGlow(frame, nil, statusbar, unit, false) + self:UpdateBorders(frame, nil, statusbar, unit, false) + local targetBar = colorFilter[statusbar] + if targetBar.flashTexture then + targetBar.flashTexture:Hide() + end + if metaTable.events[unit] then + metaFrame[unit]:UnregisterAllEvents() + metaFrame[unit]:SetScript('OnEvent', nil) end end + frame.colorFilter:Hide() + frame.colorFilter = nil end + end + end + twipe(metaTable.units) + twipe(metaTable.events) + twipe(metaTable.statusbars) + + for _, frame in ipairs(core:AggregateUnitFrames()) do + local unit = frame.unitframeType + if db.units[unit].enabled then + if not metaTable.units[unit] then + metaTable.units[unit] = {} + metaTable.events[unit] = {} + metaTable.statusbars[unit] = {} + metaFrame[unit] = CreateFrame("Frame") + end + tinsert(metaTable.units[unit], frame) - for unit, unitsCluster in pairs(metaTable.units) do - for _, frame in ipairs(unitsCluster) do - for statusbar in pairs(metaTable.statusbars[unit]) do - local tabs = metaTable.statusbars[unit][statusbar].tabs - for i = 1, #tabs do - local tab = tabs[i] - if tab.enabled and find(tab.conditions, '%S+') then - local tabsStateBlock = match(tab.conditions, '@@%[.-%]@@') - - if tabsStateBlock then - self:SortMentions(db, frame, tab.conditions, unit, statusbar, i) - end - end - end + self:ConstructHighlight(frame) - if InCombatLockdown() then - local db = E.db.unitframe.units[frame.unitframeType] - if db and (db.threatStyle == 'BORDERS' or db.threatStyle == 'HEALTHBORDER' - or db.threatStyle == 'INFOPANELBORDER') then - local colorFilter = frame.colorFilter - colorFilter.threatBordersColor = {1} - colorFilter.threatBordersActive = db.threatStyle - frame[statusbar]:ForceUpdate() - end - end + for statusbar, bar in pairs(db.units[unit].statusbars) do + local targetBar = frame.colorFilter[statusbar] + if targetBar and bar.enabled then + local barInfo = metaTable.statusbars[unit][statusbar] + if not barInfo then + metaTable.statusbars[unit][statusbar] = CopyTable(bar) + barInfo = metaTable.statusbars[unit][statusbar] - local eventsInfo = metaTable.events[unit] local unitInfo = metaTable.units[unit] - if eventsInfo and not metaFrame[unit]:GetScript('OnEvent') then - metaFrame[unit]:SetScript('OnEvent', function() - for _, frame in ipairs(unitInfo) do - if frame:IsShown() and (not frame.id - or (frame.isForced - or (GetNumPartyMembers() >= 1 or GetNumRaidMembers() >= 1))) then - for statusbar in pairs(eventsInfo) do - local frameBar = frame[statusbar] - if frameBar:IsShown() then - frameBar:ForceUpdate() + if find(bar.events, '%S+') then + tinsert(metaTable.events[unit], statusbar) + for event in gmatch(bar.events, "[%u_]+") do + metaFrame[unit]:RegisterEvent(event) + end + local eventsInfo = metaTable.events[unit] + if not metaFrame[unit]:GetScript('OnEvent') then + metaFrame[unit]:SetScript('OnEvent', function() + for _, frame in ipairs(unitInfo) do + if frame:IsShown() and (not frame.id + or (frame.isForced + or (GetNumPartyMembers() >= 1 or GetNumRaidMembers() >= 1))) then + for _, statusbar in ipairs(eventsInfo) do + local frameBar = frame[statusbar] + if frameBar:IsShown() then + frameBar:ForceUpdate() + end end end end - end - end) + end) + end end - - local barInfo = metaTable.statusbars[unit][statusbar] - local targetBar = frame.colorFilter[statusbar] - if barInfo and barInfo.frequentUpdates and statusbar ~= 'Castbar' then + if barInfo.frequentUpdates and statusbar ~= 'Castbar' then local updateThrottle = barInfo.updateThrottle or 0 - targetBar.lastUpdate = GetTime() targetBar:SetScript('OnUpdate', function(self) if GetTime() - self.lastUpdate < updateThrottle then return end @@ -1886,10 +1724,65 @@ function mod:InitAndUpdateColorFilter() end end end) + else + targetBar:SetScript('OnUpdate', nil) + end + for i = #metaTable.statusbars[unit][statusbar].tabs, 1, -1 do + local tab = metaTable.statusbars[unit][statusbar].tabs[i] + if tab.enabled and find(tab.conditions, '%S+') then + local conditions = self:SortMentions(frame, tab.conditions, unit, statusbar) + if conditions then + local luaFunction, errorMsg = loadstring(format([[ + local frame, unit, statusCheck, countCheck = ... + %s + ]], conditions)) + if not luaFunction then + core:print('LUA', L["Color Filter"], errorMsg) + tab.conditionsFunc = function() return end + else + local success, result = pcall(luaFunction, frame, unit, statusCheck, countCheck) + if not success then + core:print('FAIL', L["Color Filter"], result) + tab.conditionsFunc = function() return end + else + tab.conditionsFunc = luaFunction + end + end + tab.fetchedTexture = LSM:Fetch("statusbar", tab.texture) + else + return + end + else + tremove(metaTable.statusbars[unit][statusbar].tabs, i) + end + end + if InCombatLockdown() then + local db = E.db.unitframe.units[frame.unitframeType] + if db and (db.threatStyle == 'BORDERS' or db.threatStyle == 'HEALTHBORDER' + or db.threatStyle == 'INFOPANELBORDER') then + local colorFilter = frame.colorFilter + colorFilter.threatBordersColor = {1} + colorFilter.threatBordersActive = db.threatStyle + end end end end + if frame[statusbar] then + updateHooks(frame, bar.enabled, statusbar) + frame[statusbar]:ForceUpdate() + end end + end + end +end + +function mod:InitAndUpdateColorFilter() + if core.reload then + update(self) + elseif not updatePending then + updatePending = true + E_Delay(nil, 0.1, function() + update(self) updatePending = false end) end @@ -1898,11 +1791,11 @@ end function mod:Toggle() local enable - - for _, info in pairs(E.db.Extras.unitframes[modName].units) do - if info.enabled then enable = true break end + if not core.reload then + for _, info in pairs(E.db.Extras.unitframes[modName].units) do + if info.enabled then enable = true break end + end end - for _, func in ipairs({'Configure_Castbar', 'Construct_Castbar', 'Construct_PowerBar', 'UpdateThreat'}) do if enable then if not self:IsHooked(UF, func) then self:SecureHook(UF, func, mod[func]) end diff --git a/Modules/Unitframes/Cooldowns.lua b/Modules/Unitframes/Cooldowns.lua index e0f477d..7d1d95e 100644 --- a/Modules/Unitframes/Cooldowns.lua +++ b/Modules/Unitframes/Cooldowns.lua @@ -26,16 +26,16 @@ local UNITNAME_SUMMON_TITLES = {gsub(format(UNITNAME_SUMMON_TITLE1, 1), '[%d%p%s local function tagFunc(frame, unit) local playerName = UnitName(unit) - local activeCooldowns = activeCooldowns[playerName] + local activeCds = activeCooldowns[playerName] - if activeCooldowns and tcontains(framelist, frame) then - for i, cooldown in ipairs(activeCooldowns) do + if activeCds and tcontains(framelist, frame) then + for i, cooldown in ipairs(activeCds) do if cooldown.endTime < GetTime() then - tremove(activeCooldowns, i) + tremove(activeCds, i) end end - mod:AttachCooldowns(frame, activeCooldowns) + mod:AttachCooldowns(frame, activeCds) elseif frame.CDTracker then frame.CDTracker:Hide() end @@ -983,9 +983,9 @@ function mod:LoadConfig() type = "toggle", name = L["Shadow"], desc = L["For the important stuff."], - get = function() return #highlightedSpells > 0 and highlightedSpellsData().enabled end, + get = function() return selectedSpell() ~= "" and highlightedSpellsData().enabled end, set = function(_, value) highlightedSpellsData().enabled = value self:Toggle() end, - disabled = function() return not db[selectedType()].selectedSpell end, + disabled = function() return selectedSpell() == "" end, }, petSpell = { order = 5, @@ -994,7 +994,7 @@ function mod:LoadConfig() desc = L["Pet casts require some special treatment."], get = function() return db.petSpells[selectedSpell()] end, set = function(_, value) db.petSpells[selectedSpell()] = value and value or nil self:Toggle() end, - disabled = function() return not selectedTypeData().selectedSpell end, + disabled = function() return selectedSpell() == "" end, }, shadowSize = { order = 6, @@ -1002,9 +1002,9 @@ function mod:LoadConfig() name = L["Shadow Size"], desc = "", min = 1, max = 12, step = 1, - get = function() return #highlightedSpells > 0 and highlightedSpellsData().size or 0 end, + get = function() return selectedSpell() ~= "" and highlightedSpellsData().size or 0 end, set = function(_, value) highlightedSpellsData().size = value self:Toggle() end, - disabled = function() return #highlightedSpells == 0 or not highlightedSpellsData().enabled end, + disabled = function() return selectedSpell() == "" or not highlightedSpellsData().enabled end, }, shadowColor = { order = 7, @@ -1012,9 +1012,9 @@ function mod:LoadConfig() hasAlpha = true, name = L["Shadow Color"], desc = "", - get = function() return unpack(#highlightedSpells > 0 and highlightedSpellsData().color or {}) end, + get = function() return unpack(selectedSpell() ~= "" and highlightedSpellsData().color or {}) end, set = function(_, r, g, b, a) highlightedSpellsData().color = {r, g, b, a} self:Toggle() end, - disabled = function() return #highlightedSpells == 0 or not highlightedSpellsData().enabled end, + disabled = function() return selectedSpell() == "" or not highlightedSpellsData().enabled end, }, }, }, @@ -1136,10 +1136,10 @@ function mod:UpdateFrames(playerName, updateAll) twipe(activeCooldowns[playerName]) end frame.CDTracker:Hide() - for _, frame in ipairs(framelist) do - local unit = frame.unit + for _, f in ipairs(framelist) do + local unit = f.unit if unit and UnitName(unit) == ownerName and UnitIsPlayer(unit) then - self:AttachCooldowns(frame, activeCooldowns[ownerName], ownerName) + self:AttachCooldowns(f, activeCooldowns[ownerName], ownerName) return end end @@ -1154,9 +1154,14 @@ function mod:UpdateFrames(playerName, updateAll) end end -function mod:AttachCooldowns(frame, cooldowns, testMode) +function mod:AttachCooldowns(frame, cooldowns, inTestMode) local unitType = UnitCanAttack(frame.unit, 'player') and 'ENEMY_PLAYER' or 'FRIENDLY_PLAYER' - local db = testMode and E.db.Extras.unitframes[modName][E.db.Extras.unitframes[modName].selectedType].units[E.db.Extras.unitframes[modName].selectedUnit] or E.db.Extras.unitframes[modName][unitType].units[frame.unitframeType] + local db + if inTestMode then + db = E.db.Extras.unitframes[modName][E.db.Extras.unitframes[modName].selectedType].units[E.db.Extras.unitframes[modName].selectedUnit] + else + db = E.db.Extras.unitframes[modName][unitType].units[frame.unitframeType] + end local shown = db.showAll if not shown then @@ -1450,11 +1455,13 @@ end function mod:Toggle() local enabled - for _, type in ipairs({'FRIENDLY_PLAYER', 'ENEMY_PLAYER'}) do - for _, info in pairs(E.db.Extras.unitframes[modName][type].units) do - if info.enabled then - enabled = true - break + if not core.reload then + for _, type in ipairs({'FRIENDLY_PLAYER', 'ENEMY_PLAYER'}) do + for _, info in pairs(E.db.Extras.unitframes[modName][type].units) do + if info.enabled then + enabled = true + break + end end end end diff --git a/Modules/Unitframes/DRTracker.lua b/Modules/Unitframes/DRTracker.lua index 646d080..e851c33 100644 --- a/Modules/Unitframes/DRTracker.lua +++ b/Modules/Unitframes/DRTracker.lua @@ -473,8 +473,8 @@ function mod:LoadConfig() for id, cat in pairs(db.catList) do if id == value then db.catList[id] = nil - for cat, spellId in pairs(db.catList) do - if id == spellId then db.catList[cat] = nil end + for category, spellId in pairs(db.catList) do + if id == spellId then db.catList[category] = nil end end print(format(core.customColorAlpha..L["Category \"%s\" removed."], core.customColorBeta..cat..core.customColorAlpha)) @@ -847,6 +847,9 @@ end function mod:Toggle(db) setupDRUnits(db.units) + if core.reload then + twipe(framelist) + end if next(framelist) then self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", combatLogCheck) self:RegisterEvent("PLAYER_TARGET_CHANGED", combatLogCheck) diff --git a/Modules/Unitframes/FCF.lua b/Modules/Unitframes/FCF.lua index 8f1c486..4b9ce84 100644 --- a/Modules/Unitframes/FCF.lua +++ b/Modules/Unitframes/FCF.lua @@ -1,6 +1,6 @@ local E, L, _, P = unpack(ElvUI) local core = E:GetModule("Extras") -local mod = core:NewModule("FCF", "AceHook-3.0") +local mod = core:NewModule("FCFV2", "AceHook-3.0") local ElvUF = E.oUF local LSM = E.Libs.LSM @@ -26,6 +26,7 @@ end local testing = false local testindex = 1 local playerGUID = E.myguid or UnitGUID("player") +local schools = { heal = {2,8,32}, wound = {1,2,4,8,16,32,64} } local testEvents = { ["WOUND"] = { @@ -35,15 +36,15 @@ local testEvents = { function() local val = random() return { - random(500, 2000), -- amount - random(0, 500), -- overkill - 1, -- school (physical) - val < 0.5 and random(100, 500), -- resisted - val < 0.25 and random(100, 500), -- blocked - val > 0.75 and random(100, 500), -- absorbed - val > 0.5, -- critical - val > 0.25 and val < 0.5, -- glancing - val < 0.75 and val > 0.5 -- crushing + random(500, 2000), -- amount + random(0, 500), -- overkill + schools.wound[random(1,#schools.wound)], -- school (physical) + val < 0.15 and random(100, 500), -- resisted + val > 0.85 and random(100, 500), -- blocked + (val > 0.70 and val < 0.85) and random(100, 500), -- absorbed + val > 0.50 and val < 0.70, -- critical + val > 0.15 and val < 0.30, -- glancing + val > 0.30 and val < 0.50 -- crushing } end }, @@ -121,13 +122,15 @@ local testEvents = { "SPELL_HEAL", playerGUID, "Player", 0x511, playerGUID, "Player", 0x511, - 48089, "Circle of Healing", 0x1, + 48089, "Circle of Healing", function() + local val = random(3000, 6000) return { - random(3000, 6000), -- amount - random(0, 1000), -- overhealing - random() < 0.2 and random(100, 500), -- absorbed - random() < 0.3 and 1 -- critical + schools.heal[random(1, 3)], -- school + val, -- amount + val, -- amount + random() < 0.2 and random(0, 1000), -- overhealing + random() < 0.3 and 1 -- critical } end }, @@ -182,7 +185,7 @@ local testEvents = { } local function testMode(db) - E:Delay(db.scrollTime+0.1, function() + E:Delay(db.scrollTime/3, function() if not testing or not ElvUF.CLEUDispatcher then return end local events = {} @@ -243,56 +246,47 @@ P["Extras"]["unitframes"][modName] = { ["player"] = { ["enabled"] = false, ["animation"] = "fountain", - ["font"] = "Expressway", - ["fontSize"] = 18, - ["fontFlags"] = "", - ["textPoint"] = 'BOTTOM', - ["textRelativeTo"] = 'TOP', ["textLevel"] = 85, ["textStrata"] = 'LOW', - ["textX"] = 0, - ["textY"] = 24, ["scrollTime"] = 1.2, ["fadeTime"] = 3, - ["showIcon"] = false, - ["iconPosition"] = "before", ["blacklist"] = {}, ["events"] = { - ["ABSORB"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["BLOCK"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["DEFLECT"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["DODGE"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["ENERGIZE"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {105, 204, 240}, ["tryToColorBySchool"] = false }, - ["EVADE"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["HEAL"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {26, 204, 26}, ["tryToColorBySchool"] = false }, - ["IMMUNE"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["INTERRUPT"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["MISS"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["PARRY"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["REFLECT"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["RESIST"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["WOUND"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {179, 26, 26}, ["tryToColorBySchool"] = false }, - ["DEBUFF"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, - ["BUFF"] = { ["disabled"] = false, ["customAnimation"] = '', ["animation"] = 'fountain', ["colors"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["ABSORB"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["BLOCK"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["DEFLECT"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["DODGE"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["ENERGIZE"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {105, 204, 240}, ["tryToColorBySchool"] = false }, + ["EVADE"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["HEAL"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {26, 204, 26}, ["tryToColorBySchool"] = false }, + ["IMMUNE"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["INTERRUPT"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["MISS"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["PARRY"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["REFLECT"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["RESIST"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["WOUND"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {179, 26, 26}, ["tryToColorBySchool"] = false }, + ["DEBUFF"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, + ["BUFF"] = { ["disabled"] = false, ["iconPosition"] = "before", ["customAnimation"] = '', ["animation"] = 'fountain', ["color"] = {255, 255, 255}, ["tryToColorBySchool"] = false }, }, ["school"] = { - [SCHOOL_MASK_ARCANE] = {255, 128, 255}, - [SCHOOL_MASK_FIRE] = {255, 128, 000}, - [SCHOOL_MASK_FROST] = {128, 255, 255}, - [SCHOOL_MASK_HOLY] = {255, 230, 128}, - [SCHOOL_MASK_NATURE] = {77, 255, 77}, - [SCHOOL_MASK_NONE] = {255, 255, 255}, - [SCHOOL_MASK_PHYSICAL] = {179, 26, 26}, - [SCHOOL_MASK_SHADOW] = {128, 128, 255}, + [SCHOOL_MASK_ARCANE] = {1, 128/255, 1}, + [SCHOOL_MASK_FIRE] = {1, 128/255, 0}, + [SCHOOL_MASK_FROST] = {128/255, 1, 1}, + [SCHOOL_MASK_HOLY] = {1, 230/255, 128/255}, + [SCHOOL_MASK_NATURE] = {77/255, 1, 77/255}, + [SCHOOL_MASK_NONE] = {1, 1, 1}, + [SCHOOL_MASK_PHYSICAL] = {179/255, 26/255, 26/255}, + [SCHOOL_MASK_SHADOW] = {128/255, 128/255, 1}, -- multi-schools - [72] = {166, 192, 166}, -- SCHOOL_MASK_ASTRAL - [127] = {182, 164, 142}, -- SCHOOL_MASK_CHAOS - [28] = {153, 212, 111}, -- SCHOOL_MASK_ELEMENTAL - [126] = {183, 187, 162}, -- SCHOOL_MASK_MAGIC - [40] = {103, 192, 166}, -- SCHOOL_MASK_PLAGUE - [6] = {255, 178, 64}, -- SCHOOL_MASK_RADIANT - [36] = {192, 128, 128}, -- SCHOOL_MASK_SHADOWFLAME - [48] = {128, 192, 255}, -- SCHOOL_MASK_SHADOWFROST + [72] = {166/255, 192/255, 166/255}, -- SCHOOL_MASK_ASTRAL + [127] = {182/255, 164/255, 142/255}, -- SCHOOL_MASK_CHAOS + [28] = {153/255, 212/255, 111/255}, -- SCHOOL_MASK_ELEMENTAL + [126] = {183/255, 187/255, 162/255}, -- SCHOOL_MASK_MAGIC + [40] = {103/255, 192/255, 166/255}, -- SCHOOL_MASK_PLAGUE + [6] = {1, 178/255, 64/255}, -- SCHOOL_MASK_RADIANT + [36] = {192/255, 128/255, 128/255}, -- SCHOOL_MASK_SHADOWFLAME + [48] = {128/255, 192/255, 1}, -- SCHOOL_MASK_SHADOWFROST }, ["flags"] = { ["ABSORB"] = { ["customAnimation"] = '', ["animationsByFlag"] = false, ["animation"] = 'fountain', ["fontMult"] = 0.75 }, @@ -301,6 +295,10 @@ P["Extras"]["unitframes"][modName] = { ["CRUSHING"] = { ["customAnimation"] = '', ["animationsByFlag"] = false, ["animation"] = 'fountain', ["fontMult"] = 1.25 }, ["GLANCING"] = { ["customAnimation"] = '', ["animationsByFlag"] = false, ["animation"] = 'fountain', ["fontMult"] = 0.75 }, ["RESIST"] = { ["customAnimation"] = '', ["animationsByFlag"] = false, ["animation"] = 'fountain', ["fontMult"] = 0.75 }, + ["PERIODICWOUND"] = { ["customAnimation"] = '', ["animationsByFlag"] = false, ["animation"] = 'fountain', ["fontMult"] = 0.75 }, + ["PERIODICHEAL"] = { ["customAnimation"] = '', ["animationsByFlag"] = false, ["animation"] = 'fountain', ["fontMult"] = 0.75 }, + ["NOFLAGHEAL"] = { ["customAnimation"] = '', ["animationsByFlag"] = false, ["animation"] = 'fountain', ["fontMult"] = 0.75 }, + ["NOFLAGWOUND"] = { ["customAnimation"] = '', ["animationsByFlag"] = false, ["animation"] = 'fountain', ["fontMult"] = 0.75 }, }, }, }, @@ -322,9 +320,9 @@ function mod:LoadConfig() end core.unitframes.args[modName] = { type = "group", - name = modName, + name = "FCF", args = { - FCF = { + FCFV2 = { order = 1, type = "group", name = L["Floating Combat Feedback"], @@ -404,92 +402,20 @@ function mod:LoadConfig() set = function(info, value) selectedUnitData()[info[#info]] = value self:Toggle() end, disabled = function() return not selectedUnitData().enabled end, args = { - font = { - order = 1, - type = "select", - name = L["Font"], - desc = "", - dialogControl = "LSM30_Font", - values = function() return AceGUIWidgetLSMlists.font end, - }, - fontSize = { - order = 2, - type = "range", - name = L["Font Size"], - desc = L["There seems to be a font size limit?"], - min = 10, max = 25, step = 1, - }, - fontFlags = { - order = 3, - type = "select", - name = L["Font Flags"], - desc = "", - values = { - [""] = L["None"], - ["OUTLINE"] = "OUTLINE", - ["THINOUTLINE"] = "THINOUTLINE", - ["MONOCHROME"] = "MONOCHROME", - }, - }, - scrollTime = { - order = 4, - type = "range", - name = L["Scroll Time"], - desc = "", - min = 0.6, max = 6, step = 0.1, - }, - --[[ - fadeTime = { - order = 5, - type = "range", - name = L["Fade Time"], - desc = "", - min = 0.1, max = 3, step = 0.1, - get = function(info) - }, - ]]-- - textPoint = { - order = 6, - type = "select", - name = L["Point"], - desc = "", - values = E.db.Extras.pointOptions, - }, - textRelativeTo = { - order = 7, - type = "select", - name = L["Relative Point"], - desc = "", - values = E.db.Extras.pointOptions, - }, textLevel = { - order = 8, + order = 1, type = "range", name = L["Level"], desc = "", min = 1, max = 200, step = 1 }, textStrata = { - order = 9, + order = 2, type = "select", name = L["Strata"], desc = "", values = E.db.Extras.frameStrata, }, - textX = { - order = 10, - type = "range", - name = L["X Offset"], - desc = "", - min = -80, max = 80, step = 1, - }, - textY = { - order = 11, - type = "range", - name = L["Y Offset"], - desc = "", - min = -80, max = 80, step = 1, - }, }, }, events = { @@ -508,7 +434,11 @@ function mod:LoadConfig() desc = "", disabled = false, get = function() return selectedEvent() end, - set = function(_, value) db.selectedEvent = value end, + set = function(_, value) + db.selectedEvent = value + db.selectedFlag = "CRITICAL" + db.selectedSchool = SCHOOL_MASK_SHADOW + end, values = { ["ABSORB"] = L["ABSORB"], ["BLOCK"] = L["BLOCK"], @@ -542,46 +472,63 @@ function mod:LoadConfig() desc = "", get = function() return db.selectedSchool end, set = function(_, value) db.selectedSchool = value end, - values = { - [SCHOOL_MASK_NONE] = L["None"], - [SCHOOL_MASK_PHYSICAL] = L["Physical"], - [SCHOOL_MASK_HOLY] = L["Holy"], - [SCHOOL_MASK_FIRE] = L["Fire"], - [SCHOOL_MASK_NATURE] = L["Nature"], - [SCHOOL_MASK_FROST] = L["Frost"], - [SCHOOL_MASK_SHADOW] = L["Shadow"], - [SCHOOL_MASK_ARCANE] = L["Arcane"], - [72] = L["Astral"], - [127] = L["Chaos"], - [28] = L["Elemental"], - [126] = L["Magic"], - [40] = L["Plague"], - [6] = L["Radiant"], - [36] = L["Shadowflame"], - [48] = L["Shadowfrost"], - }, + values = function() + if selectedEvent() == 'WOUND' then + return { + [SCHOOL_MASK_NONE] = L["None"], + [SCHOOL_MASK_PHYSICAL] = L["Physical"], + [SCHOOL_MASK_HOLY] = L["Holy"], + [SCHOOL_MASK_FIRE] = L["Fire"], + [SCHOOL_MASK_NATURE] = L["Nature"], + [SCHOOL_MASK_FROST] = L["Frost"], + [SCHOOL_MASK_SHADOW] = L["Shadow"], + [SCHOOL_MASK_ARCANE] = L["Arcane"], + [72] = L["Astral"], + [127] = L["Chaos"], + [28] = L["Elemental"], + [126] = L["Magic"], + [40] = L["Plague"], + [6] = L["Radiant"], + [36] = L["Shadowflame"], + [48] = L["Shadowfrost"], + } + else + return { + [SCHOOL_MASK_HOLY] = L["Holy"], + [SCHOOL_MASK_NATURE] = L["Nature"], + [SCHOOL_MASK_SHADOW] = L["Shadow"], + } + end + end, + hidden = function() return selectedEvent() ~= 'WOUND' and selectedEvent() ~= 'HEAL' end, }, tryToColorBySchool = { order = 4, type = "toggle", name = L["Use School Colors"], desc = L["Not every event is eligible for this. But some are."], + hidden = function() return selectedEvent() ~= 'WOUND' and selectedEvent() ~= 'HEAL' end, }, - colors = { + color = { order = 5, type = "color", - name = L["Colors"], + name = L["Color"], desc = "", - get = function() local color = selectedEventData().colors return color[1], color[2], color[3] end, - set = function(_, r, g, b) selectedEventData().colors = {r, g, b} self:Toggle() end, + get = function() return unpack(selectedEventData().color or {}) end, + set = function(_, r, g, b) selectedEventData().color = {r, g, b} self:Toggle() end, }, - colorsSchool = { + colorSchool = { order = 6, type = "color", - name = L["Colors (School)"], + name = L["Color (School)"], desc = "", - get = function() local color = selectedUnitData().school[db.selectedSchool] return color[1], color[2], color[3] end, + get = function() return unpack(selectedUnitData().school[db.selectedSchool]) end, set = function(_, r, g, b) selectedUnitData().school[db.selectedSchool] = {r, g, b} self:Toggle() end, + disabled = function() + return not selectedUnitData().enabled + or selectedEventData().disabled + or (selectedEvent() ~= 'WOUND' and selectedEvent() ~= 'HEAL') + end, }, animation = { order = 7, @@ -597,8 +544,30 @@ function mod:LoadConfig() return animations end, }, - customAnimation = { + xDirection = { order = 8, + type = "select", + name = L["X Direction"], + desc = "", + values = { + [true] = L["Bounce"], + [1] = L["Right"], + [-1] = L["Left"], + } + }, + yDirection = { + order = 9, + type = "select", + name = L["Y Direction"], + desc = "", + values = { + [true] = L["Bounce"], + [1] = L["Top"], + [-1] = L["Bottom"], + } + }, + customAnimation = { + order = 10, type = "input", width = "double", multiline = true, @@ -607,6 +576,105 @@ function mod:LoadConfig() "\nreturn self.x + self.xDirection * self.radius * (1 - m_cos(m_pi / 2 * self.progress)),".. "\nself.y + self.yDirection * self.radius * m_sin(m_pi / 2 * self.progress) end"], }, + showIcon = { + order = 11, + type = "toggle", + width = "full", + name = L["Show Icon"], + desc = "", + }, + iconPosition = { + order = 12, + type = "select", + name = L["Icon Position"], + desc = "", + values = { + ["before"] = L["Before Text"], + ["after"] = L["After Text"], + }, + disabled = function() + return not selectedUnitData().enabled or selectedEventData().disabled or not selectedEventData().showIcon end, + }, + iconBounce = { + order = 13, + type = "toggle", + name = L["Bounce"], + desc = L["Flip position left-right."], + disabled = function() + return not selectedUnitData().enabled or selectedEventData().disabled or not selectedEventData().showIcon end, + }, + font = { + order = 14, + type = "select", + name = L["Font"], + desc = "", + dialogControl = "LSM30_Font", + values = function() return AceGUIWidgetLSMlists.font end, + }, + fontSize = { + order = 15, + type = "range", + name = L["Font Size"], + desc = L["There seems to be a font size limit?"], + min = 10, max = 25, step = 1, + }, + fontFlags = { + order = 16, + type = "select", + name = L["Font Flags"], + desc = "", + values = { + [""] = L["None"], + ["OUTLINE"] = "OUTLINE", + ["THINOUTLINE"] = "THINOUTLINE", + ["MONOCHROME"] = "MONOCHROME", + }, + }, + scrollTime = { + order = 17, + type = "range", + name = L["Scroll Time"], + desc = "", + min = 0.6, max = 6, step = 0.1, + }, + --[[ + fadeTime = { + order = 16, + type = "range", + name = L["Fade Time"], + desc = "", + min = 0.1, max = 3, step = 0.1, + get = function(info) + }, + ]]-- + textPoint = { + order = 18, + type = "select", + name = L["Point"], + desc = "", + values = E.db.Extras.pointOptions, + }, + textRelativeTo = { + order = 19, + type = "select", + name = L["Relative Point"], + desc = "", + values = E.db.Extras.pointOptions, + }, + textX = { + order = 20, + type = "range", + name = L["X Offset"], + desc = "", + min = -80, max = 80, step = 1, + }, + textY = { + order = 21, + type = "range", + name = L["Y Offset"], + desc = "", + min = -80, max = 80, step = 1, + }, }, }, flags = { @@ -616,23 +684,51 @@ function mod:LoadConfig() inline = true, get = function(info) return selectedFlagData()[info[#info]] end, set = function(info, value) selectedFlagData()[info[#info]] = value self:Toggle() end, - disabled = function() return not selectedUnitData().enabled or selectedEventData().disabled end, + disabled = function() return not selectedUnitData().enabled or selectedEventData().disabled or selectedFlagData().disabled end, + hidden = function() return selectedEvent() ~= 'WOUND' and selectedEvent() ~= 'HEAL' end, args = { + disabled = { + order = 0, + type = "toggle", + width = "full", + name = L["Disable"], + desc = "", + disabled = function() return not selectedUnitData().enabled or selectedEventData().disabled end, + }, flag = { order = 1, type = "select", name = L["Flag"], desc = "", get = function() return db.selectedFlag end, - set = function(_, value) db.selectedFlag = value end, - values = { - ["ABSORB" ] = L["ABSORB"], - ["BLOCK" ] = L["BLOCK"], - ["CRITICAL"] = L["CRITICAL"], - ["CRUSHING"] = L["CRUSHING"], - ["GLANCING"] = L["GLANCING"], - ["RESIST" ] = L["RESIST"], - }, + set = function(_, value) + db.selectedFlag = value + if not selectedUnitData().flags[value] then + selectedUnitData().flags[value] = CopyTable(selectedUnitData().flags["CRITICAL"]) + end + end, + values = function() + if selectedEvent() == 'WOUND' then + return { + ["ABSORB" ] = L["ABSORB"], + ["BLOCK" ] = L["BLOCK"], + ["CRITICAL" ] = L["CRITICAL"], + ["CRUSHING" ] = L["CRUSHING"], + ["GLANCING" ] = L["GLANCING"], + ["RESIST" ] = L["RESIST"], + ["PERIODICWOUND"] = L["PERIODIC"], + ["NOFLAGWOUND" ] = L["None"], + } + else + return { + ["ABSORB" ] = L["ABSORB"], + ["CRITICAL" ] = L["CRITICAL"], + ["PERIODICHEAL" ] = L["PERIODIC"], + ["NOFLAGHEAL" ] = L["None"], + } + end + end, + disabled = function() return not selectedUnitData().enabled or selectedEventData().disabled end, }, fontMult = { order = 2, @@ -641,14 +737,8 @@ function mod:LoadConfig() desc = L["There seems to be a font size limit?"], min = 0, max = 3, step = 0.25, }, - animationsByFlag = { - order = 3, - type = "toggle", - name = L["Animation by Flag"], - desc = L["Toggle to have this section handle flag animations instead.\n\nNot every event has flags."], - }, animation = { - order = 4, + order = 3, type = "select", name = L["Animation Type"], desc = "", @@ -660,8 +750,36 @@ function mod:LoadConfig() return animations end, }, - customAnimation = { + animationsByFlag = { + order = 4, + type = "toggle", + name = L["Animation by Flag"], + desc = L["Toggle to have this section handle flag animations instead.\n\nNot every event has flags."], + }, + xDirection = { order = 5, + type = "select", + name = L["X Direction"], + desc = "", + values = { + [true] = L["Bounce"], + [1] = L["Right"], + [-1] = L["Left"], + } + }, + yDirection = { + order = 6, + type = "select", + name = L["Y Direction"], + desc = "", + values = { + [true] = L["Bounce"], + [1] = L["Top"], + [-1] = L["Bottom"], + } + }, + customAnimation = { + order = 7, type = "input", multiline = true, width = "double", @@ -672,46 +790,8 @@ function mod:LoadConfig() }, }, }, - iconSettings = { - order = 5, - type = "group", - name = L["Icon Settings"], - inline = true, - get = function(info) return selectedUnitData()[info[#info]] end, - set = function(info, value) selectedUnitData()[info[#info]] = value self:Toggle() end, - disabled = function() return not selectedUnitData().enabled or selectedEventData().disabled end, - args = { - showIcon = { - order = 1, - type = "toggle", - width = "full", - name = L["Show Icon"], - desc = "", - }, - iconPosition = { - order = 2, - type = "select", - name = L["Icon Position"], - desc = "", - values = { - ["before"] = L["Before Text"], - ["after"] = L["After Text"], - }, - disabled = function() - return not selectedUnitData().enabled or selectedEventData().disabled or not selectedUnitData().showIcon end, - }, - iconBounce = { - order = 3, - type = "toggle", - name = L["Bounce"], - desc = L["Flip position left-right."], - disabled = function() - return not selectedUnitData().enabled or selectedEventData().disabled or not selectedUnitData().showIcon end, - }, - }, - }, blacklist = { - order = 6, + order = 5, type = "group", name = L["Blacklist"], inline = true, @@ -834,8 +914,9 @@ function mod:ConstructFCF(frame, info) fcf = CreateFrame("Frame", nil, frame) fcf:SetFrameStrata(info.textStrata) fcf:SetFrameLevel(info.textLevel) - fcf:Size(32, 32) - fcf:SetPoint("CENTER") + fcf:SetAllPoints(frame) + + fcf.useCLEU = true for i = 1, 6 do -- give names to these font strings to avoid breaking /fstack and /tinspect @@ -848,58 +929,80 @@ function mod:ConstructFCF(frame, info) end function mod:UpdateFCFSettings(frame) - frame:DisableElement('FloatingCombatFeedback') - + if not core.reload then + frame:DisableElement('FloatingCombatFeedback') + end local db = E.db.Extras.unitframes[modName] - for unit, info in pairs(db.units) do + for unit, data in pairs(db.units) do if frame.unitframeType == unit then - local fcf = frame.FloatingCombatFeedback - if info.enabled then - self:ConstructFCF(frame, info) - fcf = frame.FloatingCombatFeedback - fcf.useCLEU = true - fcf:ClearAllPoints() - fcf:Point(info.textPoint, frame, info.textRelativeTo, info.textX, info.textY) + if not core.reload and data.enabled then + self:ConstructFCF(frame, data) + local fcf = frame.FloatingCombatFeedback frame:EnableElement('FloatingCombatFeedback') - fcf.font = LSM:Fetch("font", info.font) - fcf.fontHeight = info.fontSize - fcf.fontFlags = info.fontFlags - fcf.scrollTime = info.scrollTime - fcf.playerOnly = info.playerOnly - --fcf.fadeTime = info.fadeTime - - fcf.format = info.showIcon and (info.iconPosition == 'before' and "|T%2$s:0:0:0:0:64:64:4:60:4:60|t %1$s" or "%1$s |T%2$s:0:0:0:0:64:64:4:60:4:60|t") or '%1$s' - fcf.iconBounce = info.showIcon and info.iconBounce or false - - fcf.blacklist = CopyTable(info.blacklist) - - for event, info in pairs(info.events) do - fcf.animationsByEvent[event] = not info.disabled and info.animation or false + fcf.playerOnly = data.playerOnly + fcf.blacklist = CopyTable(data.blacklist) - if info.tryToColorBySchool then - fcf.tryToColorBySchool[event] = true - else - fcf.tryToColorBySchool[event] = false - fcf.colors[event] = { r = info.colors[1], g = info.colors[2], b = info.colors[3] } + for event, info in pairs(data.events) do + if not info.disabled then + if info.showIcon then + fcf.iconBounce[event] = info.iconBounce + if info.iconPosition == 'before' then + fcf.formats[event] = "|T%2$s:0:0:0:0:64:64:4:60:4:60|t %1$s" + fcf.iconFormats[event]= {"|T%2$s:0:0:0:0:64:64:4:60:4:60|t %1$s", "%1$s |T%2$s:0:0:0:0:64:64:4:60:4:60|t"} + else + fcf.formats[event] = "%1$s |T%2$s:0:0:0:0:64:64:4:60:4:60|t" + fcf.iconFormats[event] = {"%1$s |T%2$s:0:0:0:0:64:64:4:60:4:60|t", "|T%2$s:0:0:0:0:64:64:4:60:4:60|t %1$s"} + end + end + if info.tryToColorBySchool then + fcf.tryToColorBySchool[event] = true + else + local color = info.color or {1,1,1} + fcf.tryToColorBySchool[event] = false + fcf.colors[event] = { r = color[1], g = color[2], b = color[3] } + end + fcf.animationsByEvent[event] = { info.animation, + tonumber(info.xDirection) or 1, + tonumber(info.yDirection) or 1, + not tonumber(info.xDirection), + info.yDirection and not tonumber(info.yDirection) or false, + } + fcf.fontData[event] = { point = info.textPoint or "CENTER", + relativeTo = info.textRelativeTo or "CENTER", + x = info.textX or 0, + y = info.textY or 24, + fontSize = info.fontSize or 18, + fontFlags = info.fontFlags or "", + font = LSM:Fetch("font", info.font or "Expressway"), + scrollTime = info.scrollTime or 1.2, + } + self:CustomAnim(frame, info.customAnimation, event) end - - self:CustomAnim(frame, info.customAnimation, event) end - for school, colors in pairs(info.school) do - fcf.schoolColors[school] = { r = colors[1], g = colors[2], b = colors[3] } + for school, color in pairs(data.school) do + fcf.schoolColors[school] = { r = color[1] or 1, g = color[2] or 1, b = color[3] or 1 } end - for flag, info in pairs(info.flags) do - fcf.multipliersByFlag[flag] = info.fontMult - if info.animationsByFlag then - fcf.animationsByFlag[flag] = info.animation - self:CustomAnim(frame, info.customAnimation, nil, flag) - elseif fcf then - fcf.animationsByFlag[flag] = nil + for flag, info in pairs(data.flags) do + if not info.disabled then + fcf.multipliersByFlag[flag] = info.fontMult + if info.animationsByFlag then + fcf.animationsByFlag[flag] = { info.animation, + tonumber(info.xDirection) or 1, + tonumber(info.yDirection) or 1, + not tonumber(info.xDirection), + info.yDirection and not tonumber(info.yDirection) or false, + } + self:CustomAnim(frame, info.customAnimation, nil, flag) + else + fcf.animationsByFlag[flag] = nil + end + else + fcf.multipliersByFlag[flag] = nil end end - elseif fcf then + elseif frame.FloatingCombatFeedback then core:Untag("fcf") end end @@ -927,4 +1030,4 @@ function mod:InitializeCallback() tinsert(core.frameUpdates, manageFCF) end -core.modules[modName] = mod.InitializeCallback +core.modules[modName] = mod.InitializeCallback \ No newline at end of file diff --git a/Modules/Unitframes/Misc.lua b/Modules/Unitframes/Misc.lua index 8d35f83..daa5ce4 100644 --- a/Modules/Unitframes/Misc.lua +++ b/Modules/Unitframes/Misc.lua @@ -59,11 +59,11 @@ function mod:LoadConfig() frame.POWERBAR_DETACHED = db.DetachPower.units[frame.unitframeType].enabled update = true else - local db = frame.db - if not db.power or not db.power.enable or not db.power.hideonnpc then - local attachPoint, x, y = UF:GetObjectAnchorPoint(frame, db.name.attachTextTo), db.name.xOffset, db.name.yOffset + local fdb = frame.db + if not fdb.power or not fdb.power.enable or not fdb.power.hideonnpc then + local attachPoint, x, y = UF:GetObjectAnchorPoint(frame, fdb.name.attachTextTo), fdb.name.xOffset, fdb.name.yOffset frame.Name:ClearAllPoints() - frame.Name:Point(db.name.position, attachPoint, db.name.position, x, y) + frame.Name:Point(fdb.name.position, attachPoint, fdb.name.position, x, y) end end end @@ -302,11 +302,11 @@ function mod:Toggle() if info.enabled then enable = true break end end end - if enable then + if not core.reload and enable then if not self:IsHooked(UF, "Configure_Power") then self:RawHook(UF, "Configure_Power", self.Configure_Power, true) end elseif self:IsHooked(UF, "Configure_Power") then self:Unhook(UF, "Configure_Power") end - if E.db.Extras.unitframes[modName].NameAutoShorten.enabled then + if not core.reload and E.db.Extras.unitframes[modName].NameAutoShorten.enabled then if not self:IsHooked(UF, "UpdateNameSettings") then self:SecureHook(UF, "UpdateNameSettings", self.UpdateNameSettings) end if not self:IsHooked(UF, "Configure_HealthBar") then self:SecureHook(UF, "Configure_HealthBar", function(self, frame) UF:UpdateNameSettings(frame, frame.childType) end) end else diff --git a/Optionals/Toolkit.lua b/Optionals/Toolkit.lua index 43bbdb3..c33b8a4 100644 --- a/Optionals/Toolkit.lua +++ b/Optionals/Toolkit.lua @@ -79,12 +79,8 @@ local function SetInside(obj, anchor, xOffset, yOffset, anchor2) obj:Point("BOTTOMRIGHT", anchor2 or anchor, "BOTTOMRIGHT", -xOffset, yOffset) end -function E:CreateGlobalShadow(db, frame) - if frame.globalShadow or not db.enabled then return end - - local size = db.size - local r, g, b, a = unpack(db.color or {0,0,0,0.8}) - +function E:CreateGlobalShadow(frame, size, r, g, b, a) + if frame.globalShadow then return end local shadow = CreateFrame("Frame", nil, frame) local strata = frame:GetFrameStrata() @@ -163,7 +159,7 @@ local function SetTemplate(frame, template, glossTex, ignoreUpdates, forcePixelM local db = E.globalShadow if db then - E:CreateGlobalShadow(db, frame) + E:CreateGlobalShadow(frame, db.size, unpack(db.color)) elseif E.pendingShadowUpdate then E.pendingShadowUpdate[frame] = true end