You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2337 lines
70 KiB

local GlobalAddonName, ExRT = ...
ExRT.F.FUNC_FILE_LOADED = true
local UnitName, GetTime, GetCursorPosition, UnitIsUnit = UnitName, GetTime, GetCursorPosition, UnitIsUnit
local select, floor, tonumber, tostring, string_sub, string_find, string_len, bit_band, type, unpack, pairs, format, strsplit = select, floor, tonumber, tostring, string.sub, string.find, string.len, bit.band, type, unpack, pairs, format, strsplit
local string_gsub, string_match = string.gsub, string.match
local RAID_CLASS_COLORS, COMBATLOG_OBJECT_TYPE_MASK, COMBATLOG_OBJECT_CONTROL_MASK, COMBATLOG_OBJECT_REACTION_MASK, COMBATLOG_OBJECT_AFFILIATION_MASK, COMBATLOG_OBJECT_SPECIAL_MASK = RAID_CLASS_COLORS, COMBATLOG_OBJECT_TYPE_MASK, COMBATLOG_OBJECT_CONTROL_MASK, COMBATLOG_OBJECT_REACTION_MASK, COMBATLOG_OBJECT_AFFILIATION_MASK, COMBATLOG_OBJECT_SPECIAL_MASK
local UnitGroupRolesAssigned = UnitGroupRolesAssigned or ExRT.NULLfunc
local GetRaidRosterInfo = GetRaidRosterInfo
do
local antiSpamArr = {}
function ExRT.F.AntiSpam(numantispam,addtime)
local t = GetTime()
if not antiSpamArr[numantispam] or antiSpamArr[numantispam] < t then
antiSpamArr[numantispam] = t + addtime
return true
else
return false
end
end
function ExRT.F.ResetAntiSpam(numantispam)
antiSpamArr[numantispam] = nil
end
end
do
--Used GLOBALS: CUSTOM_CLASS_COLORS
local classColorArray = nil
function ExRT.F.classColor(class)
classColorArray = type(CUSTOM_CLASS_COLORS)=="table" and CUSTOM_CLASS_COLORS[class] or RAID_CLASS_COLORS[class]
if classColorArray and classColorArray.colorStr then
return classColorArray.colorStr
else
return "ffbbbbbb"
end
end
function ExRT.F.classColorNum(class)
classColorArray = type(CUSTOM_CLASS_COLORS)=="table" and CUSTOM_CLASS_COLORS[class] or RAID_CLASS_COLORS[class]
if classColorArray then
return classColorArray.r,classColorArray.g,classColorArray.b
else
return 0.8,0.8,0.8
end
end
function ExRT.F.classColorByGUID(guid)
local class,_ = ""
if guid and guid ~= "" and guid ~= "0000000000000000" then
_,class = GetPlayerInfoByGUID(guid)
end
return ExRT.F.classColor(class)
end
end
function ExRT.F.clearTextTag(text,SpellLinksEnabled)
if text then
text = string_gsub(text,"|c........","")
text = string_gsub(text,"|r","")
text = string_gsub(text,"|T.-:0|t ","")
text = string_gsub(text,"|HExRT:.-|h(.-)|h","%1")
if SpellLinksEnabled then
text = string_gsub(text,"|H(spell:.-)|h(.-)|h","|cff71d5ff|H%1|h[%2]|h|r")
else
text = string_gsub(text,"|H(spell:.-)|h(.-)|h","%2")
end
return text
end
end
function ExRT.F.splitLongLine(text,maxLetters,SpellLinksEnabled)
maxLetters = maxLetters or 250
local result = {}
repeat
local lettersNow = maxLetters
if SpellLinksEnabled then
local lastC = 0
local lastR = 0
for i=1,(maxLetters-1) do
local word = string.sub(text,i,i+1)
if word == "|c" then
lastC = i
elseif word == "|r" then
lastR = i
end
end
if lastC > 0 and lastC > lastR then
lettersNow = lastC - 1
end
end
local utf8pos = 1
local textLen = string.len(text)
while true do
local char = string.sub(text,utf8pos,utf8pos)
local c = char:byte()
local lastPos = utf8pos
if c > 0 and c <= 127 then
utf8pos = utf8pos + 1
elseif c >= 194 and c <= 223 then
utf8pos = utf8pos + 2
elseif c >= 224 and c <= 239 then
utf8pos = utf8pos + 3
elseif c >= 240 and c <= 244 then
utf8pos = utf8pos + 4
else
utf8pos = utf8pos + 1
end
if utf8pos > lettersNow then
lettersNow = lastPos - 1
break
elseif utf8pos >= textLen then
break
end
end
result[#result + 1] = string.sub(text,1,lettersNow)
text = string.sub(text,lettersNow+1)
until string.len(text) < maxLetters
if string.len(text) > 0 then
result[#result + 1] = text
end
return unpack(result)
end
function ExRT.F:SetScaleFix(scale)
local l = self:GetLeft()
local t = self:GetTop()
local s = self:GetScale()
if not l or not t or not s then return end
s = scale / s
self:SetScale(scale)
local f = self:GetScript("OnDragStop")
self:ClearAllPoints()
self:SetPoint("TOPLEFT",UIParent,"BOTTOMLEFT",l / s,t / s)
if f then f(self) end
end
function ExRT.F:SetScaleFixTR(scale)
--local l = self:GetLeft() + self:GetWidth() * self:GetEffectiveScale()
local l = self:GetRight()
local t = self:GetTop()
local s = self:GetScale()
if not l or not t or not s then return end
s = scale / s
self:SetScale(scale)
local f = self:GetScript("OnDragStop")
self:ClearAllPoints()
self:SetPoint("TOPRIGHT",UIParent,"BOTTOMLEFT",l / s,t / s)
if f then f(self) end
end
function ExRT.F:GetCursorPos()
local x_f,y_f = GetCursorPosition()
local s = self.GetEffectiveScale and self:GetEffectiveScale() or self:GetParent():GetEffectiveScale()
x_f, y_f = x_f/s, y_f/s
local x,y = self:GetLeft(),self:GetTop()
x = x_f-x
y = (y_f-y)*(-1)
return x,y
end
do
local function FindAllParents(self,obj)
while obj do
if obj == self then
return true
end
obj = obj:GetParent()
end
end
function ExRT.F:IsInFocus(x,y,childs)
if not x then
x,y = ExRT.F.GetCursorPos(self)
end
local obj = GetMouseFocus()
if x > 0 and y > 0 and x < self:GetWidth() and y < self:GetHeight() and (obj == self or (childs and FindAllParents(self,obj))) then
return true
end
end
end
function ExRT.F:LockMove(isLocked,touchTexture,dontTouchMouse)
if isLocked then
if touchTexture then touchTexture:SetColorTexture(0,0,0,0.3) end
self:SetMovable(true)
if not dontTouchMouse then self:EnableMouse(true) end
else
if touchTexture then touchTexture:SetColorTexture(0,0,0,0) end
self:SetMovable(false)
if not dontTouchMouse then self:EnableMouse(false) end
end
end
local MAX_RAID_GROUP = 5
if ExRT.isClassic and not ExRT.isBC then
MAX_RAID_GROUP = 8
end
local DIFF_TO_MAX_GROUP = {
[8] = 1, --party mythic
[1] = 1, --party normal
[2] = 1, --party hc
[14] = 6, --raid normal
[15] = 6, --raid hc
[16] = 4, --raid mythic
[3] = 2, --10ppl
[5] = 2, --10ppl
[9] = 8, --40ppl
[186] = 8, --classic 40ppl
[148] = 4, --classic 20ppl
[185] = 4, --classic 20ppl
[175] = 2, --bc 10ppl
[176] = 5, --bc 25ppl
[151] = 6, --lfr
[17] = 6, --lfr
[7] = 5, --lfr [legacy]
[33] = 6, --timewalk raid
[18] = 8, --event 40ppl
[193] = 2, --10ppl hc
[194] = 5, --25ppl hc
}
function ExRT.F.GetRaidDiffMaxGroup()
local _,instance_type,difficulty = GetInstanceInfo()
if (instance_type == "party" or instance_type == "scenario") and not IsInRaid() then
return 1
elseif instance_type ~= "raid" then
return 8
elseif difficulty and DIFF_TO_MAX_GROUP[difficulty] then
return DIFF_TO_MAX_GROUP[difficulty]
else
return MAX_RAID_GROUP
end
end
function ExRT.F.GetDifficultyForCooldownReset()
local _,_,difficulty = GetInstanceInfo()
if difficulty == 3 or difficulty == 4 or difficulty == 5 or difficulty == 6 or difficulty == 7 or difficulty == 14 or difficulty == 15 or difficulty == 16 or difficulty == 17 or (ExRT.isLK and (difficulty == 175 or difficulty == 176 or difficulty == 193 or difficulty == 194)) then
return true
end
return false
end
function ExRT.F.Round(i)
return floor(i+0.5)
end
function ExRT.F.NumberInRange(i,mi,mx,incMi,incMx)
if i and ((incMi and i >= mi) or (not incMi and i > mi)) and ((incMx and i <= mx) or (not incMx and i < mx)) then
return true
end
end
function ExRT.F.delUnitNameServer(unitName)
unitName = strsplit("-",unitName)
return unitName
end
function ExRT.F.UnitCombatlogname(unit)
local name,server = UnitName(unit or "?")
if name and server and server~="" then
name = name .. "-" .. server
end
return name
end
do
local old_types = {
Player = 0,
Creature = 3,
Pet = 4,
Vehicle = 5,
GameObject = 6, --NEW
Vignette = 7, --NEW
Item = 8, --NEW Item:976:0:4000000003A91C1A
Uniq = 9, --NEW
}
function ExRT.F.GetUnitTypeByGUID(guid)
if guid then
local _type = string_match(guid,"^([A-z]+)%-")
if _type then
return old_types[_type]
end
end
end
end
function ExRT.F.UnitIsPlayerOrPet(guid)
local id = ExRT.F.GetUnitTypeByGUID(guid)
if id == 0 or id == 4 then
return true
end
end
function ExRT.F.GetUnitInfoByUnitFlag(unitFlag,infoType)
--> TYPE
if infoType == 1 then
return bit_band(unitFlag,COMBATLOG_OBJECT_TYPE_MASK)
--[1024]="player", [2048]="NPC", [4096]="pet", [8192]="GUARDIAN", [16384]="OBJECT"
--> CONTROL
elseif infoType == 2 then
return bit_band(unitFlag,COMBATLOG_OBJECT_CONTROL_MASK)
--[256]="by players", [512]="by NPC",
--> REACTION
elseif infoType == 3 then
return bit_band(unitFlag,COMBATLOG_OBJECT_REACTION_MASK)
--[16]="FRIENDLY", [32]="NEUTRAL", [64]="HOSTILE"
--> Controller affiliation
elseif infoType == 4 then
return bit_band(unitFlag,COMBATLOG_OBJECT_AFFILIATION_MASK)
--[1]="player", [2]="PARTY", [4]="RAID", [8]="OUTSIDER"
--> Special
elseif infoType == 5 then
return bit_band(unitFlag,COMBATLOG_OBJECT_SPECIAL_MASK)
--Not all ! [65536]="TARGET", [131072]="FOCUS", [262144]="MAINTANK", [524288]="MAINASSIST"
end
end
function ExRT.F.UnitIsFriendlyByUnitFlag(unitFlag)
if ExRT.F.GetUnitInfoByUnitFlag(unitFlag,2) == 256 then
return true
end
end
function ExRT.F.UnitIsFriendlyByUnitFlag2(unitFlag)
local reaction = ExRT.F.GetUnitInfoByUnitFlag(unitFlag or 0,3)
if reaction == 16 then
return true
elseif reaction == 32 then
if ExRT.F.GetUnitInfoByUnitFlag(unitFlag,2) == 256 then
return true
end
end
end
function ExRT.F.dprint(...)
return nil
end
function ExRT.F.dtime(...)
return nil
end
if ExRT.isDev then --debug or debug ultra
ExRT.F.dprint = function(...)
print(...)
end
local debugprofilestop = debugprofilestop
local lastTime = nil
ExRT.F.dtime = function(arg,...)
if arg and lastTime then
arg[#arg+1] = {debugprofilestop() - lastTime,...}
else
lastTime = debugprofilestop()
end
end
end
function ExRT.F.LinkSpell(SpellID,SpellLink)
if not SpellLink then
SpellLink = GetSpellLink(SpellID)
end
if SpellLink then
if ChatEdit_GetActiveWindow() then
ChatEdit_InsertLink(SpellLink)
else
ChatFrame_OpenChat(SpellLink)
end
end
end
function ExRT.F.LinkItem(itemID, itemLink)
if not itemLink then
if not itemID then
return
end
itemLink = select(2,GetItemInfo(itemID))
end
if not itemLink then
return
end
if IsModifiedClick("DRESSUP") then
return DressUpItemLink(itemLink)
else
if ChatEdit_GetActiveWindow() then
ChatEdit_InsertLink(itemLink)
else
ChatFrame_OpenChat(itemLink)
end
end
end
function ExRT.F.shortNumber(num)
if num < 1000 then
return tostring(num)
elseif num < 1000000 then
return format("%.1fk",num/1000)
elseif num < 1000000000 then
return format("%.2fm",num/1000000)
else
return format("%.3fM",num/1000000000)
end
end
function ExRT.F.classIconInText(class,size)
if CLASS_ICON_TCOORDS[class] then
size = size or 0
if class == "EVOKER" then
return "|Tinterface\\icons\\classicon_evoker:"..size..":"..size.."|t"
else
return "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:"..size..":"..size..":0:0:256:256:".. floor(CLASS_ICON_TCOORDS[class][1]*256) ..":"..floor(CLASS_ICON_TCOORDS[class][2]*256) ..":"..floor(CLASS_ICON_TCOORDS[class][3]*256) ..":"..floor(CLASS_ICON_TCOORDS[class][4]*256) .."|t"
end
end
end
function ExRT.F.GUIDtoID(guid)
local type,_,serverID,instanceID,zoneUID,id,spawnID = strsplit("-", guid or "")
return tonumber(id or 0)
end
function ExRT.F.table_copy(table1,table2)
table.wipe(table2)
for key,val in pairs(table1) do
table2[key] = val
end
end
function ExRT.F.table_copy2(table1)
local table2 = {}
for key,val in pairs(table1) do
if type(val) == 'table' then
table2[key] = ExRT.F.table_copy2(val)
else
table2[key] = val
end
end
return table2
end
function ExRT.F.table_wipe(arr)
if not arr or type(arr) ~= "table" then
return
end
for key,val in pairs(arr) do
if type(val) == "table" then
ExRT.F.table_wipe(val)
end
arr[key] = nil
end
end
function ExRT.F.table_find(arr,subj,pos)
if pos then
for j=1,#arr do
if arr[j][pos] == subj then
return j
end
end
else
for j=1,#arr do
if arr[j] == subj then
return j
end
end
end
end
function ExRT.F.table_find2(arr,subj)
for key,val in pairs(arr) do
if val == subj then
return key
end
end
end
function ExRT.F.table_find3(arr,subj,pos)
for j=1,#arr do
if arr[j][pos] == subj then
return arr[j]
end
end
end
function ExRT.F.table_len(arr)
local len = 0
for _ in pairs(arr) do
len = len + 1
end
return len
end
function ExRT.F.table_add(arr,add)
for i=1,#add do
arr[#arr+1] = add[i]
end
end
function ExRT.F.table_add2(arr,add)
for key,val in pairs(add) do
arr[key] = val
end
end
function ExRT.F.table_keys(arr)
local r = {}
for key,val in pairs(arr) do
r[#r+1] = key
end
return r
end
do
local function swap(array, index1, index2)
array[index1], array[index2] = array[index2], array[index1]
end
local math_random = math.random
function ExRT.F.table_shuffle(array)
local counter = #array
while counter > 1 do
local index = math_random(counter)
swap(array, index, counter)
counter = counter - 1
end
end
end
do
local printDiff = false
local printTable = nil
local function cmp(t1,t2,r,p)
local c,t = 0,0
p = p or "."
for k,v in pairs(t1) do
if type(v) == "table" then
if type(t2[k]) == "table" then
local c2,t2 = cmp(v,t2[k],false,p..k..".")
c = c + c2
t = t + t2
else
t = t + 1
if printTable then
printTable[p..k] = true
elseif printDiff then
print(p..k)
end
end
else
t = t + 1
if t1[k] == t2[k] then
c = c + 1
elseif type(v) == "number" and type(t2[k]) == "number" and tostring(v) == tostring(t2[k]) then
c = c + 1
elseif printTable then
printTable[p..k] = true
elseif printDiff then
print(p..k)
end
end
end
if not r then
local c2,t2 = cmp(t2,t1,true,p)
c = c + c2
t = t + t2
end
return c, t
end
function ExRT.F.table_compare(t1,t2,showDiff)
printDiff = showDiff
if type(printDiff) == "table" then
printTable = printDiff
printDiff = nil
else
printTable = nil
end
local c, t = cmp(t1,t2)
return c / max(1,t), c, t
end
end
function ExRT.F.table_rewrite(t1,t2)
local toRemove = {}
for k,v in pairs(t1) do
if not t2[k] then
toRemove[k] = true
elseif type(v) == "table" and type(t2[k]) == "table" then
ExRT.F.table_rewrite(v,t2[k])
else
t1[k] = t2[k]
end
end
for k,v in pairs(toRemove) do
t1[k] = nil
end
for k,v in pairs(t2) do
if not t1[k] then
t1[k] = v
end
end
end
function ExRT.F.tohex(num,size)
return format("%0"..(size or "1").."X",num)
end
function ExRT.F.UnitInGuild(unit)
unit = ExRT.F.delUnitNameServer(unit)
local gplayers = GetNumGuildMembers() or 0
for i=1,gplayers do
local name = GetGuildRosterInfo(i)
if name and ExRT.F.delUnitNameServer(name) == unit then
return true
end
end
return false
end
function ExRT.F.chatType(toSay)
local isInInstance = IsInGroup(LE_PARTY_CATEGORY_INSTANCE)
local isInParty = IsInGroup()
local isInRaid = IsInRaid()
local playerName = nil
local chat_type = (isInInstance and "INSTANCE_CHAT") or (isInRaid and "RAID") or (isInParty and "PARTY")
if not chat_type and not toSay then
chat_type = "WHISPER"
playerName = UnitName("player")
elseif not chat_type then
chat_type = "SAY"
end
return chat_type, playerName
end
function ExRT.F.IsBonusOnItem(link,bonus)
if link then
local _,itemID,enchant,gem1,gem2,gem3,gem4,suffixID,uniqueID,level,specializationID,upgradeType,instanceDifficultyID,numBonusIDs,restLink = strsplit(":",link,15)
if restLink then
local bonuses = {strsplit(":",strsplit("|h",restLink),nil)}
numBonusIDs = tonumber(numBonusIDs) or 0
local isTable = type(bonus) == "table"
for i = 1, numBonusIDs do
local bonusID = tonumber(bonuses[i]) or -999
if (isTable and bonus[bonusID]) or (not isTable and bonusID == bonus) then
return true
end
end
end
end
end
function ExRT.F.GetItemBonuses(link)
if link then
local _,itemID,enchant,gem1,gem2,gem3,gem4,suffixID,uniqueID,level,specializationID,upgradeType,instanceDifficultyID,numBonusIDs,restLink = strsplit(":",link,15)
numBonusIDs = tonumber(numBonusIDs or "?") or 0
local bonusStr = ""
for i=1,numBonusIDs do
local bonus = select(i,strsplit(":",restLink))
if bonus then
bonusStr = bonusStr .. bonus .. ":"
end
end
bonusStr = strtrim(bonusStr,":")
return bonusStr,numBonusIDs
end
return "",0
end
--/dump GMRT.F.GetItemBonuses(select(2,GameTooltip:GetItem()))
function ExRT.F.IsPlayerRLorOfficer(unitName)
local shortName = ExRT.F.delUnitNameServer(unitName)
for i=1,GetNumGroupMembers() do
--if name and (name == unitName or ExRT.F.delUnitNameServer(name) == shortName) then
if UnitIsUnit(unitName,"raid"..i) or UnitIsUnit(shortName,"raid"..i) then
local name,rank = GetRaidRosterInfo(i)
if rank > 0 then
return rank
else
return false
end
end
end
-- nil: not in party or raid
-- false: no rl, no officer
-- 1: officer
-- 2: rl
end
function ExRT.F.GetPlayerParty(unitName)
for i=1,GetNumGroupMembers() do
local name,_,subgroup = GetRaidRosterInfo(i)
if UnitIsUnit(name,unitName) then
return subgroup
end
end
return 0
end
function ExRT.F.GetOwnPartyNum()
for i=1,GetNumGroupMembers() do
local name,_,subgroup = GetRaidRosterInfo(i)
if UnitIsUnit(name,'player') then
return subgroup
end
end
return 1
end
function ExRT.F.CreateAddonMsg(...)
local result = ""
for i=1,select('#',...) do
local a = select(i,...)
result = result..(result ~= "" and "\t" or "")..tostring(a)
end
return result
end
function ExRT.F.GetPlayerRole()
local role = UnitGroupRolesAssigned('player')
if role == "HEALER" then
local _,class = UnitClass('player')
return role, (class == "PALADIN" or class == "MONK") and "MHEALER" or "RHEALER"
elseif role ~= "DAMAGER" then
--TANK, NONE
return role
else
local _,class = UnitClass('player')
local isMelee = (class == "WARRIOR" or class == "PALADIN" or class == "ROGUE" or class == "DEATHKNIGHT" or class == "MONK" or class == "DEMONHUNTER")
if class == "DRUID" then
isMelee = GetSpecialization() ~= 1
elseif class == "SHAMAN" then
isMelee = GetSpecialization() == 2
elseif class == "HUNTER" then
isMelee = GetSpecialization() == 3
end
if isMelee then
return role, "MDD"
else
return role, "RDD"
end
end
end
function ExRT.F.GetUnitRole(unit)
local role = UnitGroupRolesAssigned(unit)
if role == "HEALER" then
local _,class = UnitClass(unit)
return role, (class == "PALADIN" or class == "MONK") and "MHEALER" or "RHEALER"
elseif role ~= "DAMAGER" then
--TANK, NONE
return role
else
local _,class = UnitClass(unit)
local isMelee = (class == "WARRIOR" or class == "PALADIN" or class == "ROGUE" or class == "DEATHKNIGHT" or class == "MONK" or class == "DEMONHUNTER")
if class == "DRUID" then
isMelee = not (UnitPowerType(unit) == 8) --astral power
elseif class == "SHAMAN" then
isMelee = UnitPowerMax(unit) >= 150
elseif class == "HUNTER" then
isMelee = (ExRT.A.Inspect and UnitName(unit) and ExRT.A.Inspect.db.inspectDB[UnitName(unit)] and ExRT.A.Inspect.db.inspectDB[UnitName(unit)].spec) == 255
end
if isMelee then
return role, "MDD"
else
return role, "RDD"
end
end
end
function ExRT.F.TextureToText(textureName,widthInText,heightInText,textureWidth,textureHeight,leftTexCoord,rightTexCoord,topTexCoord,bottomTexCoord)
return "|T"..textureName..":"..(widthInText or 0)..":"..(heightInText or 0)..":0:0:"..textureWidth..":"..textureHeight..":"..
format("%d",leftTexCoord*textureWidth)..":"..format("%d",rightTexCoord*textureWidth)..":"..format("%d",topTexCoord*textureHeight)..":"..format("%d",bottomTexCoord*textureHeight).."|t"
end
function ExRT.F.GetRaidTargetText(icon,size)
size = size or 0
return ExRT.F.TextureToText([[Interface\TargetingFrame\UI-RaidTargetingIcons]],size,size,256,256,((icon-1)%4)/4,((icon-1)%4+1)/4,floor((icon-1)/4)/4,(floor((icon-1)/4)+1)/4)
end
function ExRT.F.IterateMediaData(mediaType)
local list
if LibStub then
local loaded,media = pcall(LibStub,"LibSharedMedia-3.0")
if loaded and media then
list = media:HashTable(mediaType)
end
end
return next, list or {}
end
--[[
for index, name, subgroup, class, guid, rank, level, online, isDead, combatRole in ExRT.F.IterateRoster do
<...>
end
]]
function ExRT.F.IterateRoster(maxGroup,index)
index = (index or 0) + 1
maxGroup = maxGroup or 8
if IsInRaid() then
if index > GetNumGroupMembers() then
return
end
local name, rank, subgroup, level, class, fileName, zone, online, isDead, role, isML, combatRole = GetRaidRosterInfo(index)
if subgroup > maxGroup then
return ExRT.F.IterateRoster(maxGroup,index)
end
local guid = UnitGUID(name or "raid"..index)
name = name or ""
return index, name, subgroup, fileName, guid, rank, level, online, isDead, combatRole
else
local name, rank, subgroup, level, class, fileName, online, isDead, combatRole, _
local unit = index == 1 and "player" or "party"..(index-1)
local guid = UnitGUID(unit)
if not guid then
return
end
subgroup = 1
name, _ = UnitName(unit)
name = name or ""
if _ then
name = name .. "-" .. _
end
class, fileName = UnitClass(unit)
if UnitIsGroupLeader(unit) then
rank = 2
else
rank = 1
end
level = UnitLevel(unit)
if UnitIsConnected(unit) then
online = true
end
if UnitIsDeadOrGhost(unit) then
isDead = true
end
combatRole = UnitGroupRolesAssigned(unit)
return index, name, subgroup, fileName, guid, rank, level, online, isDead, combatRole
end
end
function ExRT.F.vpairs(t)
local prev
local function it()
local k,v = next(t,prev)
prev = k
return v
end
return it
end
function ExRT.F:SafeCall(func, ...)
local res, arg1, arg2, arg3, arg4, arg5, arg6, arg7 = xpcall(func, geterrorhandler(), ...)
if res then
return arg1, arg2, arg3, arg4, arg5, arg6, arg7
end
end
do
-- UTF8
-- returns the number of bytes used by the UTF-8 character at byte i in s
-- also doubles as a UTF-8 character validator
local function utf8charbytes(s, i)
-- argument defaults
i = i or 1
-- argument checking
if type(s) ~= "string" then
error("bad argument #1 to 'utf8charbytes' (string expected, got ".. type(s).. ")")
end
if type(i) ~= "number" then
error("bad argument #2 to 'utf8charbytes' (number expected, got ".. type(i).. ")")
end
local c = strbyte(s, i)
-- determine bytes needed for character, based on RFC 3629
-- validate byte 1
if c > 0 and c <= 127 then
-- UTF8-1
return 1
elseif c >= 194 and c <= 223 then
-- UTF8-2
local c2 = strbyte(s, i + 1)
if not c2 then
error("UTF-8 string terminated early")
end
-- validate byte 2
if c2 < 128 or c2 > 191 then
error("Invalid UTF-8 character")
end
return 2
elseif c >= 224 and c <= 239 then
-- UTF8-3
local c2 = strbyte(s, i + 1)
local c3 = strbyte(s, i + 2)
if not c2 or not c3 then
error("UTF-8 string terminated early")
end
-- validate byte 2
if c == 224 and (c2 < 160 or c2 > 191) then
error("Invalid UTF-8 character")
elseif c == 237 and (c2 < 128 or c2 > 159) then
error("Invalid UTF-8 character")
elseif c2 < 128 or c2 > 191 then
error("Invalid UTF-8 character")
end
-- validate byte 3
if c3 < 128 or c3 > 191 then
error("Invalid UTF-8 character")
end
return 3
elseif c >= 240 and c <= 244 then
-- UTF8-4
local c2 = strbyte(s, i + 1)
local c3 = strbyte(s, i + 2)
local c4 = strbyte(s, i + 3)
if not c2 or not c3 or not c4 then
error("UTF-8 string terminated early")
end
-- validate byte 2
if c == 240 and (c2 < 144 or c2 > 191) then
error("Invalid UTF-8 character")
elseif c == 244 and (c2 < 128 or c2 > 143) then
error("Invalid UTF-8 character")
elseif c2 < 128 or c2 > 191 then
error("Invalid UTF-8 character")
end
-- validate byte 3
if c3 < 128 or c3 > 191 then
error("Invalid UTF-8 character")
end
-- validate byte 4
if c4 < 128 or c4 > 191 then
error("Invalid UTF-8 character")
end
return 4
else
error("Invalid UTF-8 character")
end
end
function ExRT.F.utf8len(s)
local pos = 1
local bytes = strlen(s)
local len = 0
while pos <= bytes do
len = len + 1
pos = pos + utf8charbytes(s, pos)
end
return len
end
-- functions identically to string.sub except that i and j are UTF-8 characters
-- instead of bytes
function ExRT.F.utf8sub(s, i, j)
-- argument defaults
j = j or -1
local pos = 1
local bytes = strlen(s)
local len = 0
-- only set l if i or j is negative
local l = (i >= 0 and j >= 0) or ExRT.F.utf8len(s)
local startChar = (i >= 0) and i or l + i + 1
local endChar = (j >= 0) and j or l + j + 1
-- can't have start before end!
if startChar > endChar then
return ""
end
-- byte offsets to pass to string.sub
local startByte, endByte = 1, bytes
while pos <= bytes do
len = len + 1
if len == startChar then
startByte = pos
end
pos = pos + utf8charbytes(s, pos)
if len == endChar then
endByte = pos - 1
break
end
end
return strsub(s, startByte, endByte)
end
end
function ExRT.F.GetFirstTableInText(str)
local strlen = str:len()
local i = 1
local deep = 0
local start
local inStr
local inWideStr
local wideStrEqCount = 0
while i <= strlen do
local b = str:byte(i)
if not start and not inStr and b == 123 then
start = i
elseif start and not inStr and b == 123 then
deep = deep + 1
elseif start and not inStr and b == 125 then
if deep <= 0 then
return str:sub(start,i)
else
deep = deep - 1
end
elseif not inStr and b == 34 then --"
inStr = i
elseif inStr and not inWideStr and b == 92 then --\
i = i + 1
elseif inStr and not inWideStr and b == 34 then --"
inStr = false
elseif not inStr and b == 91 then -- [ = [
local k = i + 1
local eqc = 0
while k <= strlen do
local c1 = str:byte(k)
if c1 == 61 then
eqc = eqc + 1
elseif c1 == b then
inStr = i
inWideStr = i
wideStrEqCount = eqc
break
else
break
end
k = k + 1
end
elseif inStr and inWideStr and b == 93 then -- ] = ]
local k = i + 1
local eqc = 0
while k <= strlen do
local c1 = str:byte(k)
if c1 == 61 then
eqc = eqc + 1
elseif c1 == b then
if eqc == wideStrEqCount then
i = k
inStr = false
inWideStr = false
end
break
else
break
end
k = k + 1
end
end
i = i + 1
end
end
do
local chatWindow = nil
local activeChat = "RAID"
local activeName = ""
local UpdateLines = nil
local function CreateChatWindow()
chatWindow = ELib:Template("ExRTDialogModernTemplate",UIParent)
_G["MRTToChatWindow"] = chatWindow
chatWindow:SetSize(400,300)
chatWindow:SetPoint("CENTER")
chatWindow:SetFrameStrata("DIALOG")
chatWindow:SetClampedToScreen(true)
chatWindow:EnableMouse(true)
chatWindow:SetMovable(true)
chatWindow:RegisterForDrag("LeftButton")
chatWindow:SetDontSavePosition(true)
chatWindow:SetScript("OnDragStart", function(self)
self:StartMoving()
end)
chatWindow:SetScript("OnDragStop", function(self)
self:StopMovingOrSizing()
end)
chatWindow.border = ExRT.lib:Shadow(chatWindow,20)
chatWindow.title:SetText(ExRT.L.ChatwindowName)
chatWindow.box = ExRT.lib:MultiEdit(chatWindow):Size(230,265):Point(10,-23):Font('x',11)
local chats = {
{"ME",ExRT.L.ChatwindowChatSelf},
{"SAY",ExRT.L.ChatwindowChatSay},
{"PARTY",ExRT.L.ChatwindowChatParty},
{"INSTANCE_CHAT",ExRT.L.ChatwindowChatInstance},
{"RAID",ExRT.L.ChatwindowChatRaid},
{"WHISPER",ExRT.L.ChatwindowChatWhisper},
{"TARGET",ExRT.L.ChatwindowChatWhisperTarget},
{"GUILD",ExRT.L.ChatwindowChatGuild},
{"OFFICER",ExRT.L.ChatwindowChatOfficer},
}
chatWindow.dropDown = ExRT.lib:DropDown(chatWindow,130,#chats):Size(130):Point(255,-60):SetText(ExRT.L.ChatwindowChatRaid)
chatWindow.dropDownText = ExRT.lib:Text(chatWindow,ExRT.L.ChatwindowChannel,10):Size(350,14):Point("BOTTOMLEFT",chatWindow.dropDown,"TOPLEFT",5,2):Color():Shadow()
for i=1,#chats do
local chatData = chats[i]
chatWindow.dropDown.List[i] = {
text = chatData[2],
notCheckable = true,
justifyH = "CENTER",
arg1 = chatData[1],
arg2 = chatData[2],
func = function (this,arg1,arg2)
chatWindow.dropDown:SetText(arg2)
ExRT.lib:DropDownClose()
activeChat = arg1
end
}
end
chatWindow.target = ExRT.lib:Edit(chatWindow):Size(130,20):Point(255,-115):OnChange(function (self)
activeName = self:GetText()
end)
chatWindow.targetText = ExRT.lib:Text(chatWindow,ExRT.L.ChatwindowNameEB,10):Size(350,14):Point("BOTTOMLEFT",chatWindow.target,"TOPLEFT",5,2):Bottom():Color():Shadow()
chatWindow.button = ExRT.lib:Button(chatWindow,ExRT.L.ChatwindowSend):Size(130,22):Point(255,-150):OnClick(function (self)
local lines = {strsplit("\n", chatWindow.box.EditBox:GetText())}
local channel = activeChat
local whisper = activeName
if channel == "TARGET" then
channel = "WHISPER"
whisper = ExRT.F.UnitCombatlogname("target")
if not whisper then
return
end
end
if channel == "ME" then
for i=1,#lines do
if lines[i] ~= "" then
print(lines[i])
end
end
chatWindow:Hide()
return
end
if whisper == "" then
whisper = nil
end
for i=1,#lines do
if lines[i] ~= "" then
SendChatMessage(lines[i],channel,nil,whisper)
end
end
chatWindow:Hide()
end)
chatWindow.helpText = ExRT.lib:Text(chatWindow,ExRT.L.ChatwindowHelp,10):Size(130,100):Point("TOP",chatWindow.button,"BOTTOM",0,-10):Top():Color():Shadow()
chatWindow.chk1 = ExRT.lib:Check(chatWindow,"Option 1"):Point(255,-260):OnClick(function()
UpdateLines()
end)
end
function UpdateLines()
local lines = chatWindow.lines
if not lines or type(lines)~="table" then
return
end
local editData = ""
local linesCount = #lines
local clearTags = chatWindow.clearTags
local option1 = chatWindow.option1enabled and chatWindow.chk1:GetChecked() and "%1" or ""
for i=1,linesCount do
local thisLine = lines[i]
if thisLine ~= "" then
thisLine = thisLine:gsub("@1@(.-)@1#",option1)
if clearTags then
thisLine = ExRT.F.clearTextTag(thisLine)
end
if strlen(thisLine) > 254 then
thisLine = strjoin("\n",ExRT.F.splitLongLine(thisLine,254))
end
editData = editData .. thisLine
if i ~= linesCount then
editData = editData .. "\n"
end
end
end
chatWindow.box.EditBox:SetText(editData)
end
function ExRT.F:ToChatWindow(lines,clearTags,option1Name)
if not lines or type(lines)~="table" then
return
end
if not chatWindow then
CreateChatWindow()
end
chatWindow.lines = lines
chatWindow.clearTags = clearTags
chatWindow.option1enabled = option1Name
if option1Name then
chatWindow.chk1.text:SetText(option1Name)
chatWindow.chk1:SetChecked(false)
chatWindow.chk1:Show()
else
chatWindow.chk1:Hide()
end
UpdateLines()
chatWindow:Show()
end
end
do
local alertWindow = nil
local alertFunc = nil
local alertArg1 = nil
local function CreateWindow()
alertWindow = ExRT.lib:Popup():Size(500,65)
alertWindow:SetFrameStrata("FULLSCREEN_DIALOG")
alertWindow.EditBox = ExRT.lib:Edit(alertWindow):Size(480,16):Point("TOP",0,-20)
alertWindow.OK = ExRT.lib:Button(alertWindow,ACCEPT):Size(130,20):Point("TOP",0,-40):OnClick(function (self)
alertWindow:Hide()
local input = alertWindow.EditBox:GetText()
alertFunc(alertArg1,input)
end)
alertWindow.EditBox:SetScript("OnEnterPressed",function (self)
self:GetParent().OK:Click("LeftButton")
end)
end
function ExRT.F.ShowInput(text,func,arg1,onlyNum,defText,funcOnEdit)
if not alertWindow then
CreateWindow()
end
alertWindow.OK:Enable()
alertWindow.title:SetText(text)
alertWindow.EditBox:SetScript("OnTextChanged",funcOnEdit)
alertWindow.EditBox:SetText(defText or "")
alertWindow:ClearAllPoints()
alertWindow:SetPoint("CENTER",UIParent,0,0)
alertFunc = func
alertArg1 = arg1
if onlyNum then
alertWindow.EditBox:SetNumeric(true)
else
alertWindow.EditBox:SetNumeric(false)
end
alertWindow:Show()
alertWindow.EditBox:SetFocus()
end
function ExRT.F.ShowText(text)
if not alertWindow then
CreateWindow()
end
alertWindow.title:SetText("")
alertWindow:ClearAllPoints()
alertWindow:SetPoint("CENTER",UIParent,0,0)
alertWindow.EditBox:SetNumeric(false)
alertWindow.EditBox:SetText(text)
alertWindow:Show()
alertWindow.EditBox:SetFocus()
alertFunc = ExRT.NULLfunc
end
end
---------------> Chat links hook <---------------
do
local chatLinkFormat = "|HMRT:%s:0|h|cffffff00[MRT: %s]|r|h"
local funcTable = {}
local function createChatHook()
local SetHyperlink = ItemRefTooltip.SetHyperlink
function ItemRefTooltip:SetHyperlink(link, ...)
local funcName = link:match("^MRT:([^:]+):")
if funcName then
local func = funcTable[funcName]
if not func then
return
end
func()
else
SetHyperlink(self, link, ...)
end
end
end
function ExRT.F.CreateChatLink(funcName,func,stringName)
if createChatHook then createChatHook() createChatHook = nil end
if not funcName or not stringName or type(func) ~= "function" then
return ""
end
funcTable[funcName] = func
return chatLinkFormat:format(funcName,stringName)
end
end
---------------> Export Window <---------------
do
local exportWindow
function ExRT.F:Export(stringData,hideTextInfo,windowName,onChangeFunc)
if not exportWindow then
exportWindow = ELib:Popup(ExRT.L.Export):Size(650,615)
exportWindow.Edit = ELib:MultiEdit(exportWindow):Point("TOP",0,-20):Size(640,575)
exportWindow.TextInfo = ELib:Text(exportWindow,ExRT.L.ExportInfo,11):Color():Point("BOTTOM",0,3):Size(640,15):Bottom():Left()
exportWindow:SetScript("OnHide",function(self)
self.Edit:SetText("")
end)
exportWindow.Next = ExRT.lib:Button(exportWindow,">>>"):Size(100,16):Point("BOTTOMRIGHT",0,0):OnClick(function (self)
self.now = self.now + 1
self:SetText(">>> "..self.now.."/"..#exportWindow.hugeText)
exportWindow.Edit:SetText(exportWindow.hugeText[self.now])
exportWindow.Edit.EditBox:HighlightText()
exportWindow.Edit.EditBox:SetFocus()
if self.now == #exportWindow.hugeText then
self:Hide()
end
end)
end
exportWindow.title:SetText(windowName or ExRT.L.Export)
exportWindow.Edit.OnTextChanged = onChangeFunc
exportWindow:NewPoint("CENTER",UIParent,0,0)
exportWindow.TextInfo:SetShown(not hideTextInfo)
exportWindow:Show()
if #stringData > 200000 then
exportWindow.hugeText = {}
while stringData and stringData ~= "" do
local newText = stringData:sub(1,200000)..strsplit("\n",stringData:sub(200001))
exportWindow.hugeText[#exportWindow.hugeText+1] = newText
stringData = select(2,strsplit("\n",stringData:sub(200001),2))
end
exportWindow.Next.now = 0
exportWindow.Next:Show()
exportWindow.Next:Click()
else
exportWindow.hugeText = nil
exportWindow.Next:Hide()
exportWindow.Edit:SetText(stringData)
exportWindow.Edit.EditBox:HighlightText()
exportWindow.Edit.EditBox:SetFocus()
end
end
end
do
local exportWindow
local pendingToShow
function ExRT.F:Export2(stringData)
if not exportWindow then
exportWindow = ExRT.lib:Popup("Export"):Size(650,50)
exportWindow.Edit = ExRT.lib:Edit(exportWindow):Point("TOP",0,-20):Size(640,25)
exportWindow:SetScript("OnHide",function(self)
self.Edit:SetText("")
self.onEnterFunc = nil
if pendingToShow then
stringData = select(2,next(pendingToShow))
if not stringData then
pendingToShow = nil
return
end
tremove(pendingToShow, 1)
C_Timer.After(0,function()
exportWindow.Edit:SetText(stringData)
exportWindow:Show()
end)
end
end)
exportWindow.Edit:SetScript("OnEditFocusGained", function(self)
self:HighlightText()
end)
exportWindow.Edit:SetScript("OnMouseUp", function(self, button)
self:HighlightText()
if button == "RightButton" then
self:GetParent():Hide()
end
end)
exportWindow.Edit:SetScript("OnKeyUp", function(self, c)
if (c == "c" or c == "C") and IsControlKeyDown() then
self:GetParent():Hide()
end
end)
exportWindow.Edit:SetScript("OnEnterPressed",function(self)
if self:GetParent().onEnterFunc then
self:GetParent().onEnterFunc(self:GetText())
self:GetParent():Hide()
end
end)
function exportWindow:OnShow()
self.Edit:SetFocus()
end
elseif exportWindow:IsShown() then
if not pendingToShow then
pendingToShow = {}
end
pendingToShow[#pendingToShow+1] = stringData
return
end
if type(stringData) == "function" then
exportWindow.onEnterFunc = stringData
stringData = ""
else
exportWindow.onEnterFunc = nil
end
if type(stringData) == "table" then
stringData = table.concat(ExRT.F.TableToText(stringData))
elseif type(stringData) ~= "string" then
stringData = tostring(stringData)
end
exportWindow:NewPoint("CENTER",UIParent,0,0)
exportWindow.Edit:SetText(stringData)
exportWindow:Show()
end
end
---------------> Import/Export data <---------------
do
local function StringToText(str)
if str:find("\n") then
local n = 0
if str:find("%]$") then
n = n + 1
end
while str:find("%["..string.rep("=",n).."%[") or str:find("%]"..string.rep("=",n).."%]") do
n = n + 1
end
return "["..string.rep("=",n).."["..str.."]"..string.rep("=",n).."]", true
else
return "\""..str:gsub("\\","\\\\"):gsub("\"","\\\"").."\""
end
end
local function IterateTable(t)
local prev
local index = 1
local indexMax
local isIndexDone
local function it()
if not indexMax then
local v = t[index]
if v then
index = index + 1
return index-1, v, true
else
indexMax = index - 1
end
end
local k,v = next(t,prev)
prev = k
while k and type(k)=="number" and k >= 1 and k <= indexMax do
k,v = next(t,prev)
prev = k
end
return k, v, false
end
return it
end
function ExRT.F.TableToText(t,e,b)
b = b or {}
b[t] = true
e = e or {"{"}
local ignoreIndex = false
for k,v,isIndex in IterateTable(t) do
local newline = ""
local ignore = true
if type(v) == "boolean" or type(v) == "number" or type(v) == "string" or type(v) == "table" then
ignore = false
end
if type(v) == "table" and b[v] then
ignore = true
end
if ignore then
ignoreIndex = true
elseif isIndex and not ignoreIndex then
elseif type(k)=="number" then
newline = newline .. "["..k.."]="
elseif type(k)=="string" then
if k:match("[A-Za-z_][A-Za-z_0-9]*") == k then
newline = newline .. k .. "="
else
local kstr, ismultiline = StringToText(k)
newline = newline .. "["..(ismultiline and " " or "")..kstr..(ismultiline and " " or "").."]="
end
elseif type(k)=="boolean" then
newline = newline .. "["..(k and "true" or "false").."]="
else
ignore = true
end
if not ignore then
local tableToExplore
if type(v)=="number" then
newline = newline .. v .. ","
elseif type(v)=="string" then
newline = newline .. StringToText(v)..","
elseif type(v)=="boolean" then
newline = newline ..(v and "true" or "false")..","
elseif type(v)=="table" then
newline = newline .."{"
tableToExplore = v
end
e[#e+1] = newline
if tableToExplore then
ExRT.F.TableToText(tableToExplore,e,b)
e[#e] = e[#e] .. ","
end
end
end
e[#e] = e[#e]:gsub(",$","")
e[#e+1] = "}"
return e
end
local string_byte = string.byte
function ExRT.F.TextToTable(str,map,offset)
if not map and string_byte(str, 1) == 123 then
str = str:sub(2,-2) --Expect valid table here
end
local strlen = str:len()
local i = 1
local prev = 1
map = map or {}
offset = offset or 0
local inTable, inString, inWideString
local startTable, wideStringEqCount = 1, 0
while i <= strlen do
local b1 = string_byte(str, i)
if not inString and not inTable and b1 == 123 then
inTable = 0
startTable = i
elseif not inString and inTable and b1 == 123 then
inTable = inTable + 1
elseif not inString and inTable and b1 == 125 then
if inTable == 0 then
map[startTable+offset] = i + offset
map[startTable+0.5+offset] = 1
inTable = false
else
inTable = inTable - 1
end
elseif not inString and b1 == 34 then --"
if map[i+offset+0.5] == 2 then
i = map[i+offset] - offset
else
inString = i
end
elseif inString and not inWideString and b1 == 92 then --\
i = i + 1
elseif inString and not inWideString and b1 == 34 then --"
map[inString+offset] = i + offset
map[inString+0.5+offset] = 2
inString = false
elseif not inString and b1 == 91 then -- [ = [
if map[i+offset+0.5] == 3 then
i = map[i+offset] - offset
else
local k = i + 1
local eqc = 0
while k <= strlen do
local c1 = string_byte(str, k)
if c1 == 61 then
eqc = eqc + 1
elseif c1 == b1 then
inString = i
inWideString = i
i = k
wideStringEqCount = eqc
break
else
break
end
k = k + 1
end
end
elseif inString and inWideString and b1 == 93 then -- ] = ]
local k = i + 1
local eqc = 0
while k <= strlen do
local c1 = string_byte(str, k)
if c1 == 61 then
eqc = eqc + 1
elseif c1 == b1 then
if eqc == wideStringEqCount then
i = k
map[inWideString+offset] = i + offset
map[inWideString+0.5+offset] = 3
inString = false
inWideString = false
end
break
else
break
end
k = k + 1
end
end
if not inString and not inTable and (b1 == 44 or i == strlen) then --,
map[-prev-offset] = i - (b1 == 44 and 1 or 0) + offset
prev = i + 1
end
i = i + 1
end
local res = {}
local numKey = 1
i = 1
while i <= strlen do
if map[-i-offset] then
local s, e = i, map[-i-offset] - offset
local k = s
local key, value
local isError
prev = k
while k <= e do
if map[k+offset] then
if map[k+0.5+offset] == 1 then
value = ExRT.F.TextToTable( str:sub(k+1,map[k+offset]-offset-1) ,map,k+offset)
elseif map[k+0.5+offset] == 2 then
value = str:sub(k + 1,map[k+offset]-offset-1):gsub("\\\"","\""):gsub("\\\\","\\")
elseif map[k+0.5+offset] == 3 then
value = str:sub(k,map[k+offset]-offset):gsub("^%[=*%[",""):gsub("%]=*%]$","")
end
k = map[k+offset] + 1 - offset
else
local b1 = string_byte(str, k)
if b1 == 61 then --=
if value then
key = value
value = nil
else
key = str:sub(prev, k-1):trim()
if key:find("^%[") and key:find("%]$") then
key = key:gsub("^%[",""):gsub("%]$","")
if tonumber(key) then
key = tonumber(key)
end
elseif key == "true" then
key = true
elseif key == "false" then
key = false
elseif tonumber(key) then
key = tonumber(key)
else
key = key:match("[A-Za-z_][A-Za-z_0-9]*")
end
if not key then
isError = true
break
end
end
prev = k + 1
elseif k == e and not value then
value = str:sub(prev, k):trim()
if value == "true" then
value = true
elseif value == "false" then
value = false
else
value = tonumber(value)
end
end
k = k + 1
end
end
if not isError then
if not key then
key = numKey
numKey = numKey + 1
end
res[key] = value
end
i = map[-i-offset] - offset
end
i = i + 1
end
return res
end
function ExRT.F.CreateImportExportWindows()
local function ImportOnUpdate(self, elapsed)
self.tmr = self.tmr + elapsed
if self.tmr >= 0.1 then
self.tmr = 0
self:SetScript("OnUpdate",nil)
local str = table.concat(self.buff):trim()
self.parent:Hide()
self.buff = {}
self.buffPos = 0
if self.parent.ImportFunc then
self.parent:ImportFunc(str)
end
end
end
local importWindow = ELib:Popup(ExRT.L.Import.." "..ExRT.L.ImportHelp):Size(650,100)
importWindow.Edit = ELib:MultiEdit(importWindow):Point("TOP",0,-20):Size(640,75)
importWindow:SetScript("OnHide",function(self)
self.Edit:SetText("")
end)
importWindow:SetScript("OnShow",function(self)
self.Edit.EditBox.buffPos = 0
self.Edit.EditBox.tmr = 0
self.Edit.EditBox.buff = {}
self.Edit.EditBox:SetFocus()
end)
importWindow.Edit.EditBox:SetMaxBytes(1)
importWindow.Edit.EditBox:SetScript("OnChar", function(self, c)
self.buffPos = self.buffPos + 1
self.buff[self.buffPos] = c
self:SetScript("OnUpdate",ImportOnUpdate)
end)
importWindow.Edit.EditBox.parent = importWindow
local exportWindow = ELib:Popup(ExRT.L.Export):Size(650,50)
exportWindow.Edit = ELib:Edit(exportWindow):Point("TOP",0,-20):Size(640,25)
exportWindow:SetScript("OnHide",function(self)
self.Edit:SetText("")
end)
exportWindow.Edit:SetScript("OnEditFocusGained", function(self)
self:HighlightText()
end)
exportWindow.Edit:SetScript("OnMouseUp", function(self, button)
self:HighlightText()
if button == "RightButton" then
self:GetParent():Hide()
end
end)
exportWindow.Edit:SetScript("OnKeyUp", function(self, c)
if (c == "c" or c == "C") and IsControlKeyDown() then
self:GetParent():Hide()
end
end)
function exportWindow:OnShow()
self.Edit:SetFocus()
end
return importWindow, exportWindow
end
end
-------------------> Data <--------------------
ExRT.GDB.ClassSpecializationIcons = {
[62] = "Interface\\Icons\\Spell_Holy_MagicalSentry",
[63] = "Interface\\Icons\\Spell_Fire_FireBolt02",
[64] = "Interface\\Icons\\Spell_Frost_FrostBolt02",
[65] = "Interface\\Icons\\Spell_Holy_HolyBolt",
[66] = "Interface\\Icons\\Ability_Paladin_ShieldoftheTemplar",
[70] = "Interface\\Icons\\Spell_Holy_AuraOfLight",
[71] = "Interface\\Icons\\Ability_Warrior_SavageBlow",
[72] = "Interface\\Icons\\Ability_Warrior_InnerRage",
[73] = "Interface\\Icons\\Ability_Warrior_DefensiveStance",
[102] = "Interface\\Icons\\Spell_Nature_StarFall",
[103] = "Interface\\Icons\\Ability_Druid_CatForm",
[104] = "Interface\\Icons\\Ability_Racial_BearForm",
[105] = "Interface\\Icons\\Spell_Nature_HealingTouch",
[250] = "Interface\\Icons\\Spell_Deathknight_BloodPresence",
[251] = "Interface\\Icons\\Spell_Deathknight_FrostPresence",
[252] = "Interface\\Icons\\Spell_Deathknight_UnholyPresence",
[253] = "INTERFACE\\ICONS\\ability_hunter_bestialdiscipline",
[254] = "Interface\\Icons\\Ability_Hunter_FocusedAim",
[255] = "INTERFACE\\ICONS\\ability_hunter_camouflage",
[256] = "Interface\\Icons\\Spell_Holy_PowerWordShield",
[257] = "Interface\\Icons\\Spell_Holy_GuardianSpirit",
[258] = "Interface\\Icons\\Spell_Shadow_ShadowWordPain",
[259] = "Interface\\Icons\\Ability_Rogue_DeadlyBrew",
[260] = "Interface\\Icons\\INV_Sword_30",
[261] = "Interface\\Icons\\Ability_Stealth",
[262] = "Interface\\Icons\\Spell_Nature_Lightning",
[263] = "Interface\\Icons\\Spell_Shaman_ImprovedStormstrike",
[264] = "Interface\\Icons\\Spell_Nature_MagicImmunity",
[265] = "Interface\\Icons\\Spell_Shadow_DeathCoil",
[266] = "Interface\\Icons\\Spell_Shadow_Metamorphosis",
[267] = "Interface\\Icons\\Spell_Shadow_RainOfFire",
[268] = "Interface\\Icons\\spell_monk_brewmaster_spec",
[269] = "Interface\\Icons\\spell_monk_windwalker_spec",
[270] = "Interface\\Icons\\spell_monk_mistweaver_spec",
[577] = "Interface\\Icons\\ability_demonhunter_specdps",
[581] = "Interface\\Icons\\ability_demonhunter_spectank",
[1467] = "Interface\\Icons\\classicon_evoker_devastation",
[1468] = "Interface\\Icons\\classicon_evoker_preservation",
[1473] = "Interface\\Icons\\classicon_evoker_augmentation",
}
ExRT.GDB.ClassList = {
"WARRIOR",
"PALADIN",
"HUNTER",
"ROGUE",
"PRIEST",
"DEATHKNIGHT",
"SHAMAN",
"MAGE",
"WARLOCK",
"MONK",
"DRUID",
"DEMONHUNTER",
"EVOKER",
}
ExRT.GDB.ClassSpecializationList = {
["WARRIOR"] = {71, 72, 73},
["PALADIN"] = {65, 66, 70},
["HUNTER"] = {253, 254, 255},
["ROGUE"] = {259, 260, 261},
["PRIEST"] = {256, 257, 258},
["DEATHKNIGHT"] = {250, 251, 252},
["SHAMAN"] = {262, 263, 264},
["MAGE"] = {62, 63, 64},
["WARLOCK"] = {265, 266, 267},
["MONK"] = {268, 269, 270},
["DRUID"] = {102, 103, 104, 105},
["DEMONHUNTER"] = {577, 581},
["EVOKER"] = {1467, 1468, 1473},
}
ExRT.GDB.ClassArmorType = {
WARRIOR="PLATE",
PALADIN="PLATE",
HUNTER="MAIL",
ROGUE="LEATHER",
PRIEST="CLOTH",
DEATHKNIGHT="PLATE",
SHAMAN="MAIL",
MAGE="CLOTH",
WARLOCK="CLOTH",
MONK="LEATHER",
DRUID="LEATHER",
DEMONHUNTER="LEATHER",
EVOKER="MAIL",
}
ExRT.GDB.ClassSpecializationRole = {
[62] = 'RANGE',
[63] = 'RANGE',
[64] = 'RANGE',
[65] = 'HEAL',
[66] = 'TANK',
[70] = 'MELEE',
[71] = 'MELEE',
[72] = 'MELEE',
[73] = 'TANK',
[102] = 'RANGE',
[103] = 'MELEE',
[104] = 'TANK',
[105] = 'HEAL',
[250] = 'TANK',
[251] = 'MELEE',
[252] = 'MELEE',
[253] = 'RANGE',
[254] = 'RANGE',
[255] = 'MELEE',
[256] = 'HEAL',
[257] = 'HEAL',
[258] = 'RANGE',
[259] = 'MELEE',
[260] = 'MELEE',
[261] = 'MELEE',
[262] = 'RANGE',
[263] = 'MELEE',
[264] = 'HEAL',
[265] = 'RANGE',
[266] = 'RANGE',
[267] = 'RANGE',
[268] = 'TANK',
[269] = 'MELEE',
[270] = 'HEAL',
[577] = 'MELEE',
[581] = 'TANK',
[1467] = 'RANGE',
[1468] = 'HEAL',
[1473] = 'RANGE',
}
ExRT.GDB.ClassID = {
WARRIOR=1,
PALADIN=2,
HUNTER=3,
ROGUE=4,
PRIEST=5,
DEATHKNIGHT=6,
SHAMAN=7,
MAGE=8,
WARLOCK=9,
MONK=10,
DRUID=11,
DEMONHUNTER=12,
EVOKER=13,
}
if ExRT.isCata then
ExRT.GDB.ClassSpecializationList = {
WARRIOR = {746,815,845}, --Arms,Fury,Protection
PALADIN = {831,839,855}, --Holy,Protection,Retribution
HUNTER = {811,807,809}, --Beast Mastery,Marksmanship,Survival
ROGUE = {182,181,183}, --Assassination,Combat,Subtlety
PRIEST = {760,813,795}, --Discipline,Holy,Shadow
DEATHKNIGHT = {398,399,400}, --Blood,Frost,Unholy
SHAMAN = {261,263,262}, --Elemental,Enhancement,Restoration
MAGE = {799,851,823}, --Arcane,Fire,Frost
WARLOCK = {871,867,865}, --Affliction,Demonology,Destruction
DRUID = {752,750,748}, --Balance,Feral Combat,Restoration
}
ExRT.GDB.ClassSpecializationIcons = {
[181] = 132090,
[182] = 132292,
[183] = 132320,
[261] = 136048,
[262] = 136052,
[263] = 136051,
[398] = 135770,
[399] = 135773,
[400] = 135775,
[746] = 132355,
[748] = 136041,
[750] = 132276,
[752] = 136096,
[760] = 135940,
[795] = 136207,
[799] = 135932,
[807] = 236179,
[809] = 461113,
[811] = 461112,
[813] = 237542,
[815] = 132347,
[823] = 135846,
[831] = 135920,
[839] = 236264,
[845] = 132341,
[851] = 135810,
[855] = 135873,
[865] = 136186,
[867] = 136172,
[871] = 136145,
}
ExRT.GDB.ClassSpecializationRole = {
[181] = "MELEE",
[182] = "MELEE",
[183] = "MELEE",
[261] = "RANGE",
[262] = "HEAL",
[263] = "MELEE",
[398] = "TANK",
[399] = "MELEE",
[400] = "MELEE",
[746] = "MELEE",
[748] = "HEAL",
[750] = "MELEE",
[752] = "RANGE",
[760] = "HEAL",
[795] = "RANGE",
[799] = "RANGE",
[807] = "RANGE",
[809] = "RANGE",
[811] = "RANGE",
[813] = "HEAL",
[815] = "MELEE",
[823] = "RANGE",
[831] = "HEAL",
[839] = "TANK",
[845] = "TANK",
[851] = "RANGE",
[855] = "MELEE",
[865] = "RANGE",
[867] = "RANGE",
[871] = "RANGE",
}
end
if ExRT.isClassic then
--GetClassInfo
local classLocalizateEngine = {}
if LocalizedClassList then
local classList = LocalizedClassList()
MergeTable(classLocalizateEngine, classList)
elseif FillLocalizedClassList then
FillLocalizedClassList(classLocalizateEngine)
end
ExRT.Classic.GetClassInfo = function(id)
return classLocalizateEngine[ ExRT.GDB.ClassList[id] ] or "unk"
end
--GetSpecializationInfoByID
local specializationData = {
[62] = {name="Arcane",class=8,role="DAMAGER",desc="Manipulates raw Arcane magic, destroying enemies with overwhelming power.|n|nPreferred Weapon: Staff, Wand, Dagger, Sword",icon=135932},
[63] = {name="Fire",class=8,role="DAMAGER",desc="Focuses the pure essence of Fire magic, assaulting enemies with combustive flames.|n|nPreferred Weapon: Staff, Wand, Dagger, Sword",icon=135810},
[64] = {name="Frost",class=8,role="DAMAGER",desc="Freezes enemies in their tracks and shatters them with Frost magic.|n|nPreferred Weapon: Staff, Wand, Dagger, Sword",icon=135846},
[65] = {name="Holy",class=2,role="HEALER",desc="Invokes the power of the Light to heal and protect allies and vanquish evil from the darkest corners of the world.|n|nPreferred Weapon: Sword, Mace, and Shield",icon=135920},
[66] = {name="Protection",class=2,role="TANK",desc="Uses Holy magic to shield $Ghimself:herself; and defend allies from attackers.|n|nPreferred Weapon: Sword, Mace, Axe, and Shield",icon=236264},
[70] = {name="Retribution",class=2,role="DAMAGER",desc="A righteous crusader who judges and punishes opponents with weapons and Holy magic.|n|nPreferred Weapon: Two-Handed Sword, Mace, Axe",icon=135873},
[71] = {name="Arms",class=1,role="DAMAGER",desc="A battle-hardened master of weapons, using mobility and overpowering attacks to strike $Ghis:her; opponents down.|n|nPreferred Weapon: Two-Handed Axe, Mace, Sword",icon=132355},
[72] = {name="Fury",class=1,role="DAMAGER",desc="A furious berserker unleashing a flurry of attacks to carve $Ghis:her; opponents to pieces.|n|nPreferred Weapons: Dual Two-Handed Axes, Maces, Swords",icon=132347},
[73] = {name="Protection",class=1,role="TANK",desc="A stalwart protector who uses a shield to safeguard $Ghimself:herself; and $Ghis:her; allies.|n|nPreferred Weapon: Axe, Mace, Sword, and Shield",icon=132341},
[74] = {name="Ferocity",class=0,role="DAMAGER",desc="Driven by a frenzied persistence to pursue prey, these beasts stop at nothing to achieve victory; even death is temporary for these predators.",icon=236159},
[79] = {name="Cunning",class=0,role="DAMAGER",desc="",icon=132150},
[81] = {name="Tenacity",class=0,role="TANK",desc="",icon=132121},
[102] = {name="Balance",class=11,role="DAMAGER",desc="Can shapeshift into a powerful Moonkin, balancing the power of Arcane and Nature magic to destroy enemies.|n|nPreferred Weapon: Staff, Dagger, Mace",icon=136096},
[103] = {name="Feral",class=11,role="DAMAGER",desc="Takes on the form of a great cat to deal damage with bleeds and bites.|n|nPreferred Weapon: Staff, Polearm",icon=132115},
[104] = {name="Guardian",class=11,role="TANK",desc="Takes on the form of a mighty bear to absorb damage and protect allies.|n|nPreferred Weapon: Staff, Polearm",icon=132276},
[105] = {name="Restoration",class=11,role="HEALER",desc="Channels powerful Nature magic to regenerate and revitalize allies.|n|nPreferred Weapon: Staff, Dagger, Mace",icon=136041},
[250] = {name="Blood",class=6,role="TANK",desc="A dark guardian who manipulates and corrupts life energy to sustain $Ghimself:herself; in the face of an enemy onslaught.|n|nPreferred Weapon: Two-Handed Axe, Mace, Sword",icon=135770},
[251] = {name="Frost",class=6,role="DAMAGER",desc="An icy harbinger of doom, channeling runic power and delivering vicious weapon strikes.|n|nPreferred Weapons: Dual Axes, Maces, Swords",icon=135773},
[252] = {name="Unholy",class=6,role="DAMAGER",desc="A master of death and decay, spreading infection and controlling undead minions to do $Ghis:her; bidding.|n|nPreferred Weapon: Two-Handed Axe, Mace, Sword",icon=135775},
[253] = {name="Beast Mastery",class=3,role="DAMAGER",desc="A master of the wild who can tame a wide variety of beasts to assist $Ghim:her; in combat.|n|nPreferred Weapon: Bow, Crossbow, Gun",icon=461112},
[254] = {name="Marksmanship",class=3,role="DAMAGER",desc="A master sharpshooter who excels in bringing down enemies from afar.|n|nPreferred Weapon: Bow, Crossbow, Gun",icon=236179},
[255] = {name="Survival",class=3,role="DAMAGER",desc="An adaptive ranger who favors using explosives, animal venom, and coordinated attacks with their bonded beast.|n|nPreferred Weapon: Polearm, Staff",icon=461113},
[256] = {name="Discipline",class=5,role="HEALER",desc="Uses magic to shield allies from taking damage as well as heal their wounds.|n|nPreferred Weapon: Staff, Wand, Dagger, Mace",icon=135940},
[257] = {name="Holy",class=5,role="HEALER",desc="A versatile healer who can reverse damage on individuals or groups and even heal from beyond the grave.|n|nPreferred Weapon: Staff, Wand, Dagger, Mace",icon=237542},
[258] = {name="Shadow",class=5,role="DAMAGER",desc="Uses sinister Shadow magic and terrifying Void magic to eradicate enemies.|n|nPreferred Weapon: Staff, Wand, Dagger, Mace",icon=136207},
[259] = {name="Assassination",class=4,role="DAMAGER",desc="A deadly master of poisons who dispatches victims with vicious dagger strikes.|n|nPreferred Weapons: Daggers",icon=236270},
[260] = {name="Outlaw",class=4,role="DAMAGER",desc="A ruthless fugitive who uses agility and guile to stand toe-to-toe with enemies.|n|nPreferred Weapons: Axes, Maces, Swords, Fist Weapons",icon=236286},
[261] = {name="Subtlety",class=4,role="DAMAGER",desc="A dark stalker who leaps from the shadows to ambush $Ghis:her; unsuspecting prey.|n|nPreferred Weapons: Daggers",icon=132320},
[262] = {name="Elemental",class=7,role="DAMAGER",desc="A spellcaster who harnesses the destructive forces of nature and the elements.|n|nPreferred Weapon: Mace, Dagger, and Shield",icon=136048},
[263] = {name="Enhancement",class=7,role="DAMAGER",desc="A totemic warrior who strikes foes with weapons imbued with elemental power.|n|nPreferred Weapons: Dual Axes, Maces, Fist Weapons",icon=237581},
[264] = {name="Restoration",class=7,role="HEALER",desc="A healer who calls upon ancestral spirits and the cleansing power of water to mend allies' wounds.|n|nPreferred Weapon: Mace, Dagger, and Shield",icon=136052},
[265] = {name="Affliction",class=9,role="DAMAGER",desc="A master of shadow magic who specializes in drains and damage-over-time spells.|n|nPreferred Weapon: Staff, Wand, Dagger, Sword",icon=136145},
[266] = {name="Demonology",class=9,role="DAMAGER",desc="A commander of demons who twists the souls of $Ghis:her; army into devastating power.|n|nPreferred Weapon: Staff, Wand, Dagger, Sword",icon=136172},
[267] = {name="Destruction",class=9,role="DAMAGER",desc="A master of chaos who calls down fire to burn and demolish enemies.|n|nPreferred Weapon: Staff, Wand, Dagger, Sword",icon=136186},
[268] = {name="Brewmaster",class=10,role="TANK",desc="A sturdy brawler who uses unpredictable movement and mystical brews to avoid damage and protect allies.|n|nPreferred Weapon: Staff, Polearm",icon=608951},
[269] = {name="Windwalker",class=10,role="DAMAGER",desc="A martial artist without peer who pummels foes with hands and fists.|n|nPreferred Weapons: Fist Weapons, Axes, Maces, Swords",icon=608953},
[270] = {name="Mistweaver",class=10,role="HEALER",desc="A healer who masters the mysterious art of manipulating life energies aided by the wisdom of the Jade Serpent.|n|nPreferred Weapon: Staff, Mace, Sword",icon=608952},
[535] = {name="Ferocity",class=0,role="DAMAGER",desc="Driven by a rabid persistence to pursue prey, these carnivorous beasts stop at nothing to achieve victory; even death is temporary for these predators.",icon=236159},
[536] = {name="Cunning",class=0,role="DAMAGER",desc="",icon=132150},
[537] = {name="Tenacity",class=0,role="TANK",desc="",icon=132121},
[577] = {name="Havoc",class=12,role="DAMAGER",desc="A brooding master of warglaives and the destructive power of Fel magic.|n|nPreferred Weapons: Warglaives, Swords, Axes, Fist Weapons",icon=1247264},
[581] = {name="Vengeance",class=12,role="TANK",desc="Embraces the demon within to incinerate enemies and protect their allies.|n|nPreferred Weapons: Warglaives, Swords, Axes, Fist Weapons",icon=1247265},
[1467] = {name="Devastation",class=13,role="DAMAGER",desc="Releases innate power as chaotic Red flames or focused Blue magic to bathe the battlefield in destruction. Preferred Weapon: Staff, Sword, Dagger, Mace",icon=4511811},
[1468] = {name="Preservation",class=13,role="HEALER",desc="Calls upon the Emerald Dream to rejuvenate life, and the Bronze sands of time to prevent harm. Preferred Weapon: Staff, Sword, Dagger, Mace",icon=4511812},
[1473] = {name="Augmentation",class=13,role="DAMAGER",desc="Imbues allies with the might of the Black dragons, and bends time & fate in their favor with Bronze magic. Preferred Weapon: Staff, Sword, Dagger, Mace",icon=5198700},
}
ExRT.Classic.GetSpecializationInfoByID = function(id)
local data = specializationData[id] or ExRT.NULL
return id, data.name, data.desc, data.icon, data.role, ExRT.GDB.ClassList[data.class]
end
end
ExRT.GDB.EncountersList = {
{350,652,653,654,655,656,657,658,659,660,661,662},
{331,651},
{330,649,650},
{332,623,624,625,626,627,628},
{334,730,731,732,733},
{329,618,619,620,621,622},
{335,724,725,726,727,728,729},
{129,519,520,2009,522,521,2010,2011,524,523,525,526,2012,527},
{130,2002,2003,2004,2005},
{132,1969,1966,1967,1989,1968},
{133,2026,2024,2025},
{136,2030,2027,2029,2028},
{138,1987,1985,1984,1986},
{140,1994,1996,1995,1998},
{141,1094},
{142,528,2013,530,529,2014,2015,532,531,533,534,2016,535},
{162,1107,1110,1116,1117,1112,1115,1113,1109,1121,1118,1111,1108,1120,1119,1114},
{155,1093,1092,1091,1090},
{147,1132,1136,1139,1142,1140,1137,1131,1135,1141,1164,1165,1166,1133,1138,1134,1143,1130},
{153,1978,1983,1980,1988,1981},
{156,1126,1127,1128,1129},
{157,1971,1972,1973},
{160,1974,1976,1977,1975},
{168,2018,2019,2020},
{171,2022,2023,2021},
{172,1088,1087,1086,1089,1085},
{183,2006,2007},
{184,1999,2001,2000},
{185,1992,1993,1990},
{186,1101,1100,1099,1096,1104,1097,1102,1095,1103,1098,1105,1106},
{200,1147,1149,1148,1150},
{213,1443,1444,1445,1446},
{219,593,594,595,596,597,598,599,600},
{220,492,488,486,487,490,491,493},
{221,1667,1668,1669,1675,1676,1670,1671,1672},
{225,1144,1145,1146},
{226,379,378,380,381,382},
{230,547,548,549,551,552,553,554,1887},
{232,663,664,665,666,667,668,669,670,671,672},
{233,785,784,786,787,788,789,790,791,792,793},
{234,343,344,345,346,350,347,348,349,361,362,363,364,365,366,367,368},
{242,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245},
{246,1935,1936,1937,1938},
{247,718,719,720,721,722,723},
{248,1084},
{250,267,268,269,270,271,272,274,273,275},
{256,1889,1890},
{258,1902,1903,1904},
{260,1908,1909,1910,1911},
{261,1922,1923,1924},
{262,1945,1946,1947,1948},
{263,1942,1943,1944},
{265,1939,1940,1941},
{266,1925,1926,1927,1928,1929},
{267,1930,1931,1932,1933,1934},
{269,1913,1914,1915,1916},
{272,1899,1900,250,1901},
{273,1919,1920,1921},
{274,1905,1906,1907},
{277,1052,1053,1054,1055},
{279,585,586,587,588,589,590,591,592},
{280,422,423,427,424,425,426,428,429},
{282,1033,1250,1332},
{283,1040,1038,1039,1037,1036},
{285,1027,1024,1022,1023,1025,1026},
{287,610,611,612,613,614,615,616,617},
{291,1064,1065,1063,1062,1060,1081},
{293,1051,1050,1048,1049},
{294,1030,1032,1028,1029,1082,1083},
{297,1080,1076,1075,1077,1074,1079,1078},
{300,1662,1663,1664,1665,1666},
{301,1656,438,1659,1660,1661},
{302,444,446,447,448,449,450},
{306,451,452,453,454,455,456,457,458,459,460,461,462,463},
{310,1069,1070,1071,1073,1072},
{317,473,474,476,475,477,478,472,479,480,481,482,483,484,1885},
{319,709,710,711,712,713,714,715,716,717},
{322,1045,1044,1046,1047},
{324,1056,1059,1058,1057},
{325,1043,1041,1042},
{328,1035,1034},
{333,1189,1190,1191,1192,1193,1194},
{337,1178,1179,1188,1180,1181,1182},
{339,601,602,603,604,605,606,607,608,609},
{347,1891,1892,1893},
{348,1894,1895,1897,1898},
{367,1197,1204,1205,1206,1200,1185,1203},
{398,1272,1273,1274},
{399,1337,1340,1339},
{401,1881,1882,1883,1884,1271},
{409,1292,1294,1295,1296,1297,1298,1291,1299},
{429,1418,1417,1416,1439},
{431,1422,1421,1420},
{435,1423,1424,1425},
{437,1397,1405,1406,1419},
{439,1412,1413,1414},
{443,1303,1304,1305,1306},
{453,1442,1509,1510,1441},
{456,1409,1505,1506,1431},
{457,1465,1502,1447,1464},
{471,1395,1390,1434,1436,1500,1407},
{474,1507,1504,1463,1498,1499,1501},
{476,1426,1427,1428,1429,1430},
{508,1577,1575,1570,1565,1578,1573,1572,1574,1576,1559,1560,1579,1580,1581},
{554,1563,1564,1571,1587},
{556,1602,1598,1624,1604,1622,1600,1606,1603,1595,1594,1599,1601,1593,1623,1605},
{573,1655,1653,1652,1654},
{574,1677,1688,1679,1682},
{593,1686,1685,1678,1714},
{595,1749,1748,1750,1754},
{601,1698,1699,1700,1701},
{606,1715,1732,1736},
{616,1761,1758,1759,1760,1762},
{620,1746,1757,1751,1752,1756},
{624,1755,1770,1801},
{703,1805,1806,1807,1808,1809},
{708,1822,1823,1824},
{710,1815,1850,1816,1817,1818},
{713,1810,1811,1812,1813,1814},
{731,1790,1791,1792,1793},
{732,1845,1846,1847,1848,1851,1852,1855,1856},
{733,1836,1837,1838,1839},
{749,1825,1826,1827,1828,1829},
{751,1832,1833,1834,1835},
{761,1868,1869,1870},
{790,1879,1880,1888,1917,1950,1951,1952,1953,1949},
{809,1957,1954,1961,1960,1964,1965,1959,2017,2031},
{845,2055,2057,2039,2053},
{903,2065,2066,2067,2068},
{934,2084,2085,2086,2087},
{936,2093,2094,2095,2096},
{974,2101,2102,2103,2104},
{1010,2105,2106,2107,2108},
{1015,2113,2114,2115,2116,2117},
{1041,2111,2118,2112,2123},
{1162,2098,2097,2109,2099,2100},
{1038,2124,2125,2126,2127},
{1039,2130,2131,2132,2133},
{1004,2139,2142,2140,2143},
{1490,2290,2292,2312,2291,2257,2258,2259,2260},
{1666,2387,2388,2389,2390},
{1674,2382,2384,2385,2386},
{1669,2397,2392,2393},
{1663,2401,2380,2403,2381},
{1693,2357,2356,2358,2359},
{1683,2391,2365,2366,2364,2404},
{1679,2395,2394,2400,2396},
{1675,2360,2361,2362,2363},
{2096,2570,2568,2567,2569},
{2071,2555,2556,2557,2558,2559},
{2093,2637,2636,2581,2580},
{2080,2613,2612,2610,2611},
{2097,2562,2563,2564,2565},
{2095,2609,2606,2623},
{2073,2582,2585,2583,2584},
{2082,2615,2616,2617,2618},
{610,1721,1706,1720,1722,1719,1723,1705},--HM
{596,1696,1691,1693,1694,1689,1692,1690,1713,1695,1704},--BF
{661,1778,1785,1787,1798,1786,1783,1788,1794,1777,1800,1784,1795,1799},--HFC
{777,1853,1841,1873,1854,1876,1877,1864},--EN
{806,1958,1962,2008},--tov
{764,1849,1865,1867,1871,1862,1886,1842,1863,1872,1866},--nighthold
{850,2032,2048,2036,2037,2050,2054,2052,2038,2051},--tos
{909,2076,2074,2064,2070,2075,2082,2069,2088,2073,2063,2092},--antorus
{1148,2144,2141,2136,2128,2134,2145,2135,2122},--uldir
{1358,2265,2263,2284,2266,2285,2271,2268,2272,2276,2280,2281}, --bfd
{1345,2269,2273}, --storms
{1512,2298,2305,2289,2304,2303,2311,2293,2299}, --ethernal place
{1582,2329,2327,2334,2328,2336,2333,2331,2335,2343,2345,2337,2344}, --nyalotha
{1735,2398,2418,2402,2383,2405,2406,2412,2399,2417,2407}, --castle Nathria
{1998,2423,2433,2429,2432,2434,2430,2436,2431,2422,2435}, --sod
{2047,2512,2540,2553,2544,2539,2542,2529,2546,2543,2549,2537}, --sfo
{2119,2587,2639,2590,2592,2635,2605,2614,2607}, --voti
{2166,2688,2682,2687,2693,2680,2689,2683,2684,2685}, --a
{"10.2",2232,2820,2709,2737,2731,2728,2708,2824,2786,2677}, --d
}
local ACTUAL_RAID = 1735
local ACTUAL_DUNG = 1666
if UnitLevel'player' > 60 then
ACTUAL_DUNG = 2096
ACTUAL_RAID = 2119
end
do
local function StringVerToNumber(ver)
local i = 0
local r = 0
for n in ver:gmatch("%d+") do
r = r + tonumber(n) * (10 ^ i)
i = i - 2
end
return r
end
local ver_now = StringVerToNumber(GetBuildInfo())
for i=#ExRT.GDB.EncountersList,1,-1 do
local t = ExRT.GDB.EncountersList[i]
if type(t[1]) == "string" then
if StringVerToNumber(t[1]) > ver_now then
tremove(ExRT.GDB.EncountersList, i)
else
tremove(t, 1)
end
elseif t[1] == ACTUAL_DUNG then
--stop loop for old data
break
end
end
end
function ExRT.F.GetEncountersList(onlyRaid,onlyActual,reverse)
local new = {}
local isActual,isRaid
for _,v in ipairs(ExRT.GDB.EncountersList) do
if v[1] == 610 then
isRaid = true
isActual = false
elseif v[1] == ACTUAL_DUNG then
isActual = true
elseif v[1] == ACTUAL_RAID then
isActual = true
end
if (not onlyActual or isActual) and (not onlyRaid or isRaid) then
new[#new+1] = v
end
end
if reverse then
local len = #new
for i=1,floor(len/2) do
new[i], new[len+1-i] = new[len+1-i], new[i]
end
end
return new
end