Mercurial > wow > crossrealmassist
comparison CrossRealmAssist.lua @ 13:1f68e8154947
New alpha build
| author | ShadowTheAge |
|---|---|
| date | Thu, 12 Mar 2015 22:51:35 +0300 |
| parents | 0deef890ec99 |
| children | c97b3a4e5feb |
comparison
equal
deleted
inserted
replaced
| 12:0deef890ec99 | 13:1f68e8154947 |
|---|---|
| 1 CrossRealmAssist = LibStub("AceAddon-3.0"):NewAddon("CrossRealmAssist", "AceEvent-3.0", "AceConsole-3.0", "AceTimer-3.0") | 1 CrossRealmAssist = LibStub("AceAddon-3.0"):NewAddon("CrossRealmAssist", "AceEvent-3.0", "AceConsole-3.0", "AceTimer-3.0") |
| 2 local addon = CrossRealmAssist; | 2 local addon = CrossRealmAssist; |
| 3 local wholib = LibStub:GetLibrary('LibWho-2.0'):Library() | 3 local wholib = LibStub:GetLibrary('LibWho-2.0'):Library() |
| 4 local ScrollingTable = LibStub("ScrollingTable"); | 4 local ScrollingTable = LibStub("ScrollingTable"); |
| 5 | 5 local ldb = LibStub("LibDataBroker-1.1") |
| 6 local homeRealm, realmSep, gui, btRefresh, btQuick, btManual, lbRealm, lbStatus, playerName, lfgui, lfgTabSelected, lfgTable, lbThrottle | 6 local minimapIcon = LibStub("LibDBIcon-1.0") |
| 7 local db | |
| 8 | |
| 9 local homeRealm, realmSep, gui, btRefresh, btSettings, btQuick, btManual, lbRealm, lbStatus, playerName, lfgui, lfgTabSelected, lfgTable, lbThrottle, curLfgGroup, sheduledScan, wasInGroup, inInstance | |
| 10 local settingsMenu | |
| 11 local hintShown | |
| 7 | 12 |
| 8 local tabs = {} | 13 local tabs = {} |
| 9 local curRealmStat | 14 local curRealmStat |
| 10 local scanstate=0 | 15 local scanstate=0 |
| 11 local recentRealms={} | 16 local recentRealms={} |
| 12 local recentgroups={} | 17 local recentgroups={} |
| 18 local autoScanGroups={} | |
| 13 local active=false | 19 local active=false |
| 14 | 20 |
| 15 local lfgGroups={ | 21 local lfgGroups={ |
| 16 6, -- Custom | 22 6, -- Custom |
| 17 10, -- Ashran | 23 10, -- Ashran |
| 18 1, -- Quests | 24 1, -- Quests |
| 19 3 -- Raids | 25 3, -- Raids |
| 26 8 -- BGs | |
| 20 } | 27 } |
| 21 | 28 |
| 22 local StatusTable = { | 29 local StatusTable = { |
| 23 ["invited"]="Invited", | 30 ["invited"]="Invited", |
| 24 ["declined"]="Declined", | 31 ["declined"]="Declined", |
| 25 ["timedout"]="Timed out", | 32 ["timedout"]="Timed out", |
| 26 ["applied"]="Applied", | 33 ["applied"]="Applied", |
| 27 ["cancelled"]="Join cancelled", | 34 ["cancelled"]="Join cancelled", |
| 28 ["inviteaccepted"]="Joined", | 35 ["inviteaccepted"]="Joined", |
| 29 ["_init"]="Join request" | 36 ["_init"]="Join request", |
| 37 ["_skip"]="Skipped" | |
| 30 } | 38 } |
| 31 | 39 local DefaultWidgetPos = {x=0, y=200, to="CENTER"} |
| 32 local curLfgGroup | 40 local SettingsDefaults={ |
| 33 local sheduledScan | 41 global={ |
| 34 local wasInGroup | 42 minimap = {}, |
| 35 local inInstance | 43 widgetPos=DefaultWidgetPos, |
| 44 quickJoinHint = true, | |
| 45 quickJoin={[6]=1,[10]=1} | |
| 46 } | |
| 47 } | |
| 36 | 48 |
| 37 | 49 |
| 38 -- Utils functions | 50 -- Utils functions |
| 39 | 51 |
| 40 local function PlayerName(fullname) | 52 local function PlayerName(fullname) |
| 90 widget.TooltipFactory = factory; | 102 widget.TooltipFactory = factory; |
| 91 widget:SetScript("OnEnter", ShowTooltip) | 103 widget:SetScript("OnEnter", ShowTooltip) |
| 92 widget:SetScript("OnLeave", HideTooltip) | 104 widget:SetScript("OnLeave", HideTooltip) |
| 93 end | 105 end |
| 94 | 106 |
| 95 local function SelectLfgTab(tab) | 107 local function TabClick(tab) |
| 108 if tab == lfgTabSelected then return end | |
| 109 addon.LfgScan(tab.searchID) | |
| 110 end | |
| 111 | |
| 112 local function changeTab(tab) | |
| 96 PanelTemplates_DeselectTab(lfgTabSelected) | 113 PanelTemplates_DeselectTab(lfgTabSelected) |
| 97 lfgTabSelected = tab | 114 lfgTabSelected = tab |
| 98 addon.LfgScan(tab.searchID) | |
| 99 PanelTemplates_SelectTab(lfgTabSelected) | 115 PanelTemplates_SelectTab(lfgTabSelected) |
| 100 end | 116 end |
| 101 | 117 |
| 102 local function realmToolip() | 118 local function realmToolip() |
| 103 if not curRealmStat then return end | 119 if not curRealmStat then return end |
| 116 GameTooltip:AddDoubleLine(data.realm, percent, 0.5,0.5,0.5,0.5,0.5,0.5) | 132 GameTooltip:AddDoubleLine(data.realm, percent, 0.5,0.5,0.5,0.5,0.5,0.5) |
| 117 end | 133 end |
| 118 end | 134 end |
| 119 end | 135 end |
| 120 | 136 |
| 137 local function ClearRealmHistory() | |
| 138 recentRealms = {} | |
| 139 addon:updateCurrentRealm() | |
| 140 if lfgTable then lfgTable:Refresh() end | |
| 141 end | |
| 142 | |
| 121 | 143 |
| 122 | 144 |
| 123 | 145 |
| 124 | 146 |
| 125 | 147 |
| 151 local ago = GetTime() - recentgroups[fullname].time; | 173 local ago = GetTime() - recentgroups[fullname].time; |
| 152 visCoef = math.min(1,ago/600) | 174 visCoef = math.min(1,ago/600) |
| 153 end | 175 end |
| 154 | 176 |
| 155 local leaderRealm = 3 -- recently visited realms | 177 local leaderRealm = 3 -- recently visited realms |
| 156 if (realm ~= "???") then leaderRealm = (5 - (recentRealms[realm] or 0)) end | 178 local realmVis = recentRealms[realm] |
| 179 local leaderRealm = 3; | |
| 180 if realmVis then | |
| 181 local ago = GetTime() - realmVis | |
| 182 leaderRealm = 1 + 2*math.min(1,ago/600); | |
| 183 end | |
| 157 | 184 |
| 158 local countWeight = 4 -- count weight | 185 local countWeight = 4 -- count weight |
| 159 if pcount >= 39 or pcount <= 1 then countWeight = 1 | 186 if pcount >= 39 or pcount <= 1 then countWeight = 1 |
| 160 elseif pcount >= 35 or pcount <= 4 then countWeight = 2 | 187 elseif pcount >= 35 or pcount <= 4 then countWeight = 2 |
| 161 elseif pcount >= 30 or pcount <= 10 then countWeight = 3 | 188 elseif pcount >= 30 or pcount <= 10 then countWeight = 3 |
| 166 elseif time > 300 then ageWeight = 3 end | 193 elseif time > 300 then ageWeight = 3 end |
| 167 | 194 |
| 168 return leaderRealm * countWeight * visCoef * autoinvWeight * ageWeight; | 195 return leaderRealm * countWeight * visCoef * autoinvWeight * ageWeight; |
| 169 end | 196 end |
| 170 | 197 |
| 171 local function ShowLfgInfo(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...) | 198 local function AddLfgGroupInfo(id, short) |
| 172 if not realrow then return end | 199 local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(id) |
| 173 local rowdata = scrollingTable:GetRow(realrow); | |
| 174 local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rowdata.id) | |
| 175 local friends = bnetfr+charfr+guild | 200 local friends = bnetfr+charfr+guild |
| 176 GameTooltip:SetOwner(rowFrame, "ANCHOR_BOTTOMLEFT",-10,25) | |
| 177 GameTooltip:ClearLines() | 201 GameTooltip:ClearLines() |
| 178 GameTooltip:AddLine(caption,1,1,1) | 202 GameTooltip:AddLine(caption,1,1,1) |
| 179 addTooltipLineIcon(desc ~= "", desc, nil, 0.5, 0.5, 0.5, true) | 203 addTooltipLineIcon(desc ~= "", desc, nil, 0.5, 0.5, 0.5, true) |
| 180 local name, realm = PlayerName(fullname) | 204 local name, realm = PlayerName(fullname) |
| 205 GameTooltip:AddDoubleLine("Players:",pcount) | |
| 181 GameTooltip:AddDoubleLine("Leader:",name) | 206 GameTooltip:AddDoubleLine("Leader:",name) |
| 182 GameTooltip:AddDoubleLine("Leader realm:",realm) | 207 GameTooltip:AddDoubleLine("Leader realm:",realm) |
| 183 GameTooltip:AddLine(" ") | 208 if recentRealms[realm] then |
| 184 GameTooltip:AddDoubleLine("Players:",pcount) | 209 local ago = GetTime() - recentRealms[realm] |
| 185 addTooltipLineIcon(ilvl > 0, "Min. ilvl: "..ilvl, READY_CHECK_WAITING_TEXTURE, 1, 1, 0) | 210 GameTooltip:AddDoubleLine("Realm visited",SecondsToTime(ago, false, false, 1, false).." ago",1,0.5,0,1,0.5,0) |
| 186 addTooltipLineIcon(voice ~= "", "Voice: "..voice, READY_CHECK_WAITING_TEXTURE, 1, 1, 0) | 211 else |
| 187 addTooltipLineIcon(friends > 0, "Friends: "..friends, READY_CHECK_WAITING_TEXTURE, 1, 1, 0) | 212 GameTooltip:AddDoubleLine(" ","Realm not visited!",0,0,0,0,1,0) |
| 188 addTooltipLineIcon(autoinv, "Autoinvite!", READY_CHECK_READY_TEXTURE, 0, 1, 0) | 213 end |
| 189 local visitinfo = recentgroups[fullname] | 214 if not short then |
| 190 if visitinfo then | 215 addTooltipLineIcon(ilvl > 0, "Min. ilvl: "..ilvl, READY_CHECK_WAITING_TEXTURE, 1, 1, 0) |
| 191 local ago = GetTime() - visitinfo.time; | 216 addTooltipLineIcon(voice ~= "", "Voice: "..voice, READY_CHECK_WAITING_TEXTURE, 1, 1, 0) |
| 192 GameTooltip:AddDoubleLine(StatusTable[visitinfo.status] or visitinfo.status,SecondsToTime(ago, false, false, 1, false).." ago",1,0,0,1,0,0) | 217 addTooltipLineIcon(friends > 0, "Friends: "..friends, READY_CHECK_WAITING_TEXTURE, 1, 1, 0) |
| 193 GameTooltip:AddTexture(READY_CHECK_NOT_READY_TEXTURE) | 218 addTooltipLineIcon(autoinv, "Autoinvite!", READY_CHECK_READY_TEXTURE, 0, 1, 0) |
| 219 local visitinfo = recentgroups[fullname] | |
| 220 if visitinfo then | |
| 221 local ago = GetTime() - visitinfo.time; | |
| 222 GameTooltip:AddDoubleLine(StatusTable[visitinfo.status] or visitinfo.status,SecondsToTime(ago, false, false, 1, false).." ago",1,0,0,1,0,0) | |
| 223 GameTooltip:AddTexture(READY_CHECK_NOT_READY_TEXTURE) | |
| 224 end | |
| 194 end | 225 end |
| 195 GameTooltip:Show() | 226 GameTooltip:Show() |
| 227 end | |
| 228 | |
| 229 local function ShowLfgInfo(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...) | |
| 230 if not realrow then return end | |
| 231 local rowdata = scrollingTable:GetRow(realrow); | |
| 232 GameTooltip:SetOwner(rowFrame, "ANCHOR_BOTTOMLEFT",-10,25) | |
| 233 AddLfgGroupInfo(rowdata.id); | |
| 196 end | 234 end |
| 197 | 235 |
| 198 local function updateTableData(rowFrame, cellFrame, data, cols, row, realrow, column, fShow, table, ...) | 236 local function updateTableData(rowFrame, cellFrame, data, cols, row, realrow, column, fShow, table, ...) |
| 199 if fShow then | 237 if fShow then |
| 200 local rowdata = table:GetRow(realrow); | 238 local rowdata = table:GetRow(realrow); |
| 226 local name = select(12, C_LFGList.GetSearchResultInfo(id)) | 264 local name = select(12, C_LFGList.GetSearchResultInfo(id)) |
| 227 local pname, realm = PlayerName(name); | 265 local pname, realm = PlayerName(name); |
| 228 return realm | 266 return realm |
| 229 end | 267 end |
| 230 | 268 |
| 269 local COLOR_YELLOW = {r=1,g=1,b=0,a=1} | |
| 270 local COLOR_GREEN = {r=0,g=1,b=0,a=1} | |
| 271 local function updateRealmColor(id) | |
| 272 local name = select(12, C_LFGList.GetSearchResultInfo(id)) | |
| 273 local pname, realm = PlayerName(name); | |
| 274 return recentRealms[realm] and COLOR_YELLOW or COLOR_GREEN; | |
| 275 end | |
| 276 | |
| 231 local function filterTable(self, row) | 277 local function filterTable(self, row) |
| 232 local delisted = select(11, C_LFGList.GetSearchResultInfo(row.id)) | 278 local delisted = select(11, C_LFGList.GetSearchResultInfo(row.id)) |
| 233 return not delisted; | 279 return not delisted; |
| 234 end | 280 end |
| 235 | 281 |
| 236 function addon:UpdateResponseData(event, result) | 282 function addon:UpdateResponseData(event, result) |
| 283 if not lfgTable then return end | |
| 237 if select(11, C_LFGList.GetSearchResultInfo(result)) then | 284 if select(11, C_LFGList.GetSearchResultInfo(result)) then |
| 238 lfgTable:SetFilter(filterTable) | 285 lfgTable:SetFilter(filterTable) |
| 239 end | 286 end |
| 240 hasLfgListChanges = true | 287 hasLfgListChanges = true |
| 241 end | 288 end |
| 250 local data = list[i]; | 297 local data = list[i]; |
| 251 local cols = {} | 298 local cols = {} |
| 252 local row = {rid} | 299 local row = {rid} |
| 253 cols[1] = {value=updateGroupName,args=row} | 300 cols[1] = {value=updateGroupName,args=row} |
| 254 cols[2] = {value=updateGroupCount,args=row} | 301 cols[2] = {value=updateGroupCount,args=row} |
| 255 cols[3] = {value=updateGroupRealm,args=row} | 302 cols[3] = {value=updateGroupRealm,args=row,color=updateRealmColor,colorargs=row} |
| 256 cols[4] = {} | 303 cols[4] = {} |
| 257 table.insert(tableData, {cols=cols,id=rid,weight=WeightLfgItem(rid)}) | 304 table.insert(tableData, {cols=cols,id=rid,weight=WeightLfgItem(rid)}) |
| 258 end | 305 end |
| 259 table.sort(tableData, sortByWeight); | 306 table.sort(tableData, sortByWeight); |
| 260 lfgTable:SetData(tableData) | 307 lfgTable:SetData(tableData) |
| 261 end | 308 end |
| 262 | 309 |
| 263 local function JoinGroup(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...) | 310 local function JoinGroup(rid) |
| 311 local tank, heal, dd = C_LFGList.GetAvailableRoles() | |
| 312 addon:SetGroupJoinStatus(rid, "_init") | |
| 313 C_LFGList.ApplyToGroup(rid, "", tank, heal, dd) | |
| 314 end | |
| 315 | |
| 316 local function TableCellClick(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...) | |
| 264 if not realrow or not canJoinGroup() then return end | 317 if not realrow or not canJoinGroup() then return end |
| 265 local rowdata = scrollingTable:GetRow(realrow); | 318 local rowdata = scrollingTable:GetRow(realrow); |
| 266 local tank, heal, dd = C_LFGList.GetAvailableRoles() | 319 JoinGroup(rowdata.id) |
| 267 addon:SetGroupJoinStatus(rowdata.id, "_init") | |
| 268 C_LFGList.ApplyToGroup(rowdata.id, "", tank, heal, dd) | |
| 269 end | 320 end |
| 270 | 321 |
| 271 | 322 |
| 272 | 323 |
| 273 | 324 |
| 274 | 325 |
| 275 | 326 |
| 276 -- Addon functions and gui constructors | 327 -- Addon functions and gui constructors |
| 277 | 328 |
| 329 function addon.ShowMmTooltip(tooltip) | |
| 330 tooltip:AddLine("Cross Realm Assist",1,1,1) | |
| 331 tooltip:Show() | |
| 332 end | |
| 333 | |
| 334 --[[function addon.MmClick(self, button) | |
| 335 if button == "RightButton" then | |
| 336 addon.ShowSettings(self) | |
| 337 else | |
| 338 addon:Activate() | |
| 339 end | |
| 340 end]] | |
| 341 | |
| 342 function addon:OnInitialize() | |
| 343 db = LibStub("AceDB-3.0"):New("CrossRealmAssistDB", SettingsDefaults) | |
| 344 local minimapData = ldb:NewDataObject("CrossRealmAssistMinimapIcon",{ | |
| 345 type = "data source", | |
| 346 text = "Cross Realm Assist", | |
| 347 icon = "Interface/Icons/INV_Misc_GroupNeedMore", | |
| 348 OnClick = addon.Activate, | |
| 349 OnTooltipShow = addon.ShowMmTooltip | |
| 350 }) | |
| 351 minimapIcon:Register("CrossRealmAssistMinimapIcon", minimapData, db.global.minimap) | |
| 352 end | |
| 353 | |
| 278 function addon:OnEnable() | 354 function addon:OnEnable() |
| 279 local tabCount = table.getn(lfgGroups) | |
| 280 realmSep = _G.REALM_SEPARATORS | 355 realmSep = _G.REALM_SEPARATORS |
| 281 playerName = UnitName("player") | 356 playerName = UnitName("player") |
| 282 homeRealm = GetRealmName() | 357 homeRealm = GetRealmName() |
| 283 addon:RegisterChatCommand("cra", "Activate") | 358 addon:RegisterChatCommand("cra", "Activate") |
| 284 addon:RegisterChatCommand("crossrealmassist", "Activate") | 359 addon:RegisterChatCommand("crossrealmassist", "Activate") |
| 294 if active then return end | 369 if active then return end |
| 295 active=true | 370 active=true |
| 296 wasInGroup = IsInGroup() | 371 wasInGroup = IsInGroup() |
| 297 if not gui then addon:CreateUI() end | 372 if not gui then addon:CreateUI() end |
| 298 addon:updateCurrentRealm(); | 373 addon:updateCurrentRealm(); |
| 299 addon:ForceRefreshZone(); | 374 addon:RefreshZoneAndClearHistory(); |
| 300 gui:Show() | 375 gui:Show() |
| 301 addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "ForceRefreshZone") | 376 addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "RefreshZoneAndClearHistory") |
| 302 addon:RegisterEvent("SCENARIO_UPDATE", "ForceRefreshZone") | 377 addon:RegisterEvent("SCENARIO_UPDATE", "RefreshZoneAndClearHistory") |
| 303 addon:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED", "LfgResponseData") | 378 addon:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED", "LfgResponseData") |
| 304 addon:RegisterEvent("LFG_LIST_SEARCH_RESULT_UPDATED", "UpdateResponseData") | 379 addon:RegisterEvent("LFG_LIST_SEARCH_RESULT_UPDATED", "UpdateResponseData") |
| 305 addon:RegisterEvent("LFG_LIST_SEARCH_FAILED", "LfgScanFailed") | 380 addon:RegisterEvent("LFG_LIST_SEARCH_FAILED", "LfgScanFailed") |
| 306 addon:RegisterEvent("GROUP_ROSTER_UPDATE", "updatePartyInfo") | 381 addon:RegisterEvent("GROUP_ROSTER_UPDATE", "updatePartyInfo") |
| 307 addon:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED", "updateAppStatus") | 382 addon:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED", "updateAppStatus") |
| 308 addon.LfgScan(lfgGroups[1]) | 383 addon.LfgScan(addon.GetNextAutoScanCategory() or 1) |
| 309 end | 384 end |
| 310 | 385 |
| 311 function addon:Deactivate() | 386 function addon:Deactivate() |
| 312 if not active then return end | 387 if not active then return end |
| 313 active = false | 388 active = false |
| 326 | 401 |
| 327 function addon:SetStatus(status) | 402 function addon:SetStatus(status) |
| 328 if status then | 403 if status then |
| 329 lbStatus:SetText(status) | 404 lbStatus:SetText(status) |
| 330 else | 405 else |
| 331 lbStatus:SetText("") -- TODO | 406 lbStatus:SetText("") |
| 332 end | 407 end |
| 408 end | |
| 409 | |
| 410 local function stopMovingWidget() | |
| 411 gui:StopMovingOrSizing() | |
| 412 local point,_,_,x,y = gui:GetPoint(1); | |
| 413 db.global.widgetPos = {x=x,y=y,to=point} | |
| 333 end | 414 end |
| 334 | 415 |
| 335 function addon:CreateUI() | 416 function addon:CreateUI() |
| 336 gui = setupWidget(CreateFrame("Frame","CrossRealmAssistMainUI",nil,"InsetFrameTemplate3"), {SetFrameStrata="LOW",SetWidth=208,SetHeight=60,EnableMouse=true,SetMovable=true}) | 417 gui = setupWidget(CreateFrame("Frame","CrossRealmAssistMainUI",nil,"InsetFrameTemplate3"), {SetFrameStrata="LOW",SetWidth=208,SetHeight=60,EnableMouse=true,SetMovable=true}) |
| 337 local title = setupWidget(CreateFrame("Frame",nil,gui), {SetWidth=190,SetHeight=18,EnableMouse=true,RegisterForDrag="LeftButton"}, 0, 6); | 418 local title = setupWidget(CreateFrame("Frame",nil,gui), {SetWidth=190,SetHeight=18,EnableMouse=true,RegisterForDrag="LeftButton"}, 0, 6); |
| 338 title:SetScript("OnDragStart", function() gui:StartMoving() end) | 419 title:SetScript("OnDragStart", function() gui:StartMoving() end) |
| 339 title:SetScript("OnDragStop", function() gui:StopMovingOrSizing() end) | 420 title:SetScript("OnDragStop", stopMovingWidget) |
| 340 gui:SetScript("OnHide", addon.Deactivate) | 421 gui:SetScript("OnHide", addon.Deactivate) |
| 341 setupTooltip(title, "ANCHOR_TOP", realmToolip) | 422 setupTooltip(title, "ANCHOR_TOP", realmToolip) |
| 342 | 423 |
| 343 lbRealm = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontNormal"), {SetWidth=200,SetHeight=18}, 0, 6) | 424 lbRealm = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontNormal"), {SetWidth=200,SetHeight=18}, 0, 6) |
| 344 lbStatus = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontHighlightSmallLeft"), {SetWidth=200,SetHeight=10}, 6, 23) | 425 lbStatus = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontHighlightSmallLeft"), {SetWidth=200,SetHeight=10}, 6, 23) |
| 345 | 426 |
| 346 btQuick = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{SetWidth=90,SetHeight=20,SetText="Quick join"},4,36) | 427 btQuick = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{SetWidth=90,SetHeight=20,SetText="Quick join"},4,36) |
| 428 btQuick:RegisterForClicks("RightButtonUp","LeftButtonUp") | |
| 347 btQuick:SetScript("OnClick",addon.DoAutoAction) | 429 btQuick:SetScript("OnClick",addon.DoAutoAction) |
| 430 setupTooltip(btQuick, "ANCHOR_BOTTOM", addon.actionTooltip) | |
| 348 btManual = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{SetWidth=90,SetHeight=20,SetText="Manual join"},94,36) | 431 btManual = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{SetWidth=90,SetHeight=20,SetText="Manual join"},94,36) |
| 349 btManual:SetScript("OnClick",addon.ShowManualLfg) | 432 btManual:SetScript("OnClick",addon.ShowManualLfg) |
| 350 setupWidget(CreateFrame("Button",nil,gui,"UIPanelCloseButton"),{EnableMouse=true,SetWidth=20,SetHeight=20},188,0) | 433 setupWidget(CreateFrame("Button",nil,gui,"UIPanelCloseButton"),{EnableMouse=true,SetWidth=20,SetHeight=20},188,0) |
| 351 | 434 |
| 352 btRefresh = setupWidget(CreateFrame("Button",nil,gui,"UIPanelSquareButton"),{SetWidth=20,SetHeight=20},184,36) | 435 btRefresh = setupWidget(CreateFrame("Button",nil,gui,"UIPanelSquareButton"),{SetWidth=20,SetHeight=20},184,16) |
| 353 btRefresh.icon:SetTexture("Interface/BUTTONS/UI-RefreshButton") | 436 btRefresh.icon:SetTexture("Interface/BUTTONS/UI-RefreshButton") |
| 354 btRefresh.icon:SetTexCoord(0,1,0,1); | 437 btRefresh.icon:SetTexCoord(0,1,0,1); |
| 355 btRefresh:SetScript("OnClick",addon.RefreshZone) | 438 btRefresh:SetScript("OnClick",addon.RefreshZone) |
| 356 | 439 |
| 357 gui:SetPoint("CENTER",0,0) | 440 btSettings = setupWidget(CreateFrame("Button",nil,gui,"UIPanelSquareButton"),{SetWidth=20,SetHeight=20},184,36) |
| 441 btSettings.icon:SetTexture("Interface/Worldmap/Gear_64Grey") | |
| 442 btSettings.icon:SetTexCoord(0.1,0.9,0.1,0.9); | |
| 443 btSettings:SetScript("OnClick",addon.ShowSettings) | |
| 444 | |
| 445 local savedPos = db.global.widgetPos | |
| 446 gui:SetPoint(savedPos.to,savedPos.x,savedPos.y) | |
| 358 addon:UpdateAutoButtonStatus() | 447 addon:UpdateAutoButtonStatus() |
| 359 end | 448 end |
| 360 | 449 |
| 361 function addon:ShowManualLfg() | 450 function addon:ShowManualLfg() |
| 362 if not lfgui then addon:CreateLFGUI() end | 451 if not lfgui then addon:CreateLFGUI() end |
| 383 {name="#",width=30,align="CENTER"}, | 472 {name="#",width=30,align="CENTER"}, |
| 384 {name="Realm",width=120,align="RIGHT"}, | 473 {name="Realm",width=120,align="RIGHT"}, |
| 385 {name="",width=50,DoCellUpdate=updateTableData} | 474 {name="",width=50,DoCellUpdate=updateTableData} |
| 386 },15,16,nil,lfgui); | 475 },15,16,nil,lfgui); |
| 387 | 476 |
| 388 lfgTable:RegisterEvents({OnEnter=ShowLfgInfo,OnLeave=HideTooltip,OnClick=JoinGroup}) | 477 lfgTable:RegisterEvents({OnEnter=ShowLfgInfo,OnLeave=HideTooltip,OnClick=TableCellClick}) |
| 389 | 478 |
| 390 setupWidget(lfgTable.frame, nil, 10, 45); | 479 setupWidget(lfgTable.frame, nil, 10, 45); |
| 391 lfgTable.frame:SetBackdrop(nil) | 480 lfgTable.frame:SetBackdrop(nil) |
| 392 lfgui:SetPoint("CENTER",0,0) | 481 lfgui:SetPoint("CENTER",0,0) |
| 393 refreshLFGList() | 482 refreshLFGList() |
| 404 function addon:CreateTabs() | 493 function addon:CreateTabs() |
| 405 local prevTab | 494 local prevTab |
| 406 for i=1,#lfgGroups do | 495 for i=1,#lfgGroups do |
| 407 local tab = CreateFrame("Button","$parentTab"..i,lfgui,"CharacterFrameTabButtonTemplate") | 496 local tab = CreateFrame("Button","$parentTab"..i,lfgui,"CharacterFrameTabButtonTemplate") |
| 408 tab:SetText((C_LFGList.GetCategoryInfo(lfgGroups[i]))); | 497 tab:SetText((C_LFGList.GetCategoryInfo(lfgGroups[i]))); |
| 409 tab.searchID = lfgGroups[i]; | 498 tab.searchID = i; |
| 410 tab:SetID(i); | 499 tab:SetID(i); |
| 411 PanelTemplates_TabResize(tab, 0) | 500 PanelTemplates_TabResize(tab, 0) |
| 412 if i == 1 then | 501 if i == 1 then |
| 413 tab:SetPoint("TOPLEFT", lfgui, "BOTTOMLEFT", 10, 7) | 502 tab:SetPoint("TOPLEFT", lfgui, "BOTTOMLEFT", 10, 7) |
| 414 lfgTabSelected = tab | 503 lfgTabSelected = tab |
| 504 else | |
| 505 tab:SetPoint("TOPLEFT", prevTab, "TOPRIGHT",-15,0) | |
| 506 end | |
| 507 if curLfgGroup == i then | |
| 415 PanelTemplates_SelectTab(tab) | 508 PanelTemplates_SelectTab(tab) |
| 416 else | 509 else |
| 417 tab:SetPoint("TOPLEFT", prevTab, "TOPRIGHT",-15,0) | |
| 418 PanelTemplates_DeselectTab(tab) | 510 PanelTemplates_DeselectTab(tab) |
| 419 end | 511 end |
| 420 tab:SetScript("OnClick", SelectLfgTab) | 512 tab:SetScript("OnClick", TabClick) |
| 421 tabs[i] = tab | 513 tabs[i] = tab |
| 422 prevTab = tab | 514 prevTab = tab |
| 423 end | 515 end |
| 424 end | 516 end |
| 425 | 517 |
| 427 | 519 |
| 428 function addon.refreshLfgCurrent() | 520 function addon.refreshLfgCurrent() |
| 429 addon.LfgScan(curLfgGroup) | 521 addon.LfgScan(curLfgGroup) |
| 430 end | 522 end |
| 431 | 523 |
| 524 function addon.GetNextAutoScanCategory() | |
| 525 for i=1,#lfgGroups do | |
| 526 if not autoScanGroups[i] and db.global.quickJoin[lfgGroups[i]] and i ~= curLfgGroup then return i end | |
| 527 end | |
| 528 return nil | |
| 529 end | |
| 530 | |
| 432 function addon.LfgScan(group) | 531 function addon.LfgScan(group) |
| 433 if lfgTable then lfgTable:SetData({}) end | 532 if lfgTable then |
| 533 lfgTable:SetData({}) | |
| 534 changeTab(tabs[group]) | |
| 535 end | |
| 434 lfgScanInProgress = true | 536 lfgScanInProgress = true |
| 435 curLfgGroup = group | 537 curLfgGroup = group |
| 436 C_LFGList.Search(curLfgGroup,"") | 538 C_LFGList.Search(lfgGroups[curLfgGroup],"") |
| 437 end | 539 end |
| 438 | 540 |
| 439 function addon:LfgScanFailed(event, reason) | 541 function addon:LfgScanFailed(event, reason) |
| 440 if reason == "throttled" then | 542 if reason == "throttled" then |
| 441 addon:ScheduleTimer(addon.LfgScan, 2, curLfgGroup) | 543 addon:ScheduleTimer(addon.LfgScan, 2, curLfgGroup) |
| 442 lbThrottle:SetText("LFG scan is delayed (throttled).\nThis page will update automatically...") | 544 end |
| 443 else | 545 if lbThrottle then |
| 444 lbThrottle:SetText("Scan failed ("..reason..")") | 546 if reason == "throttled" then |
| 445 end | 547 lbThrottle:SetText("LFG scan is delayed (throttled).\nThis page will update automatically...") |
| 446 lbThrottle:Show() | 548 else |
| 549 lbThrottle:SetText("Scan failed ("..reason..")") | |
| 550 end | |
| 551 lbThrottle:Show() | |
| 552 end | |
| 447 end | 553 end |
| 448 | 554 |
| 449 function addon:LfgResponseData() | 555 function addon:LfgResponseData() |
| 450 lfgScanInProgress = false; | 556 lfgScanInProgress = false; |
| 557 addon:UpdateAutoButtonStatus() | |
| 451 if lbThrottle then lbThrottle:Hide() end | 558 if lbThrottle then lbThrottle:Hide() end |
| 452 refreshLFGList() | 559 refreshLFGList() |
| 453 end | 560 end |
| 454 | 561 |
| 455 function addon:updateAppStatus(event, id, status, oldstatus) | 562 function addon:updateAppStatus(event, id, status, oldstatus) |
| 460 addon:SetGroupJoinStatus(id, status) | 567 addon:SetGroupJoinStatus(id, status) |
| 461 end | 568 end |
| 462 | 569 |
| 463 function addon:SetGroupJoinStatus(id, status) | 570 function addon:SetGroupJoinStatus(id, status) |
| 464 local name = select(12, C_LFGList.GetSearchResultInfo(id)) | 571 local name = select(12, C_LFGList.GetSearchResultInfo(id)) |
| 465 recentgroups[name] = {status=status, time=GetTime()} | 572 if name then |
| 573 recentgroups[name] = {status=status, time=GetTime()} | |
| 574 end | |
| 575 end | |
| 576 | |
| 577 function addon:RealmVisited(realm, head) | |
| 578 recentRealms[realm] = GetTime() | |
| 466 end | 579 end |
| 467 | 580 |
| 468 function addon:updatePartyInfo() | 581 function addon:updatePartyInfo() |
| 469 local realms = {} | 582 local realms = {} |
| 470 local inGroup = IsInGroup() | 583 local inGroup = IsInGroup() |
| 478 addon:AddUnitIdStat("party"..i, realms) | 591 addon:AddUnitIdStat("party"..i, realms) |
| 479 end | 592 end |
| 480 end | 593 end |
| 481 end | 594 end |
| 482 if inGroup ~= wasInGroup then | 595 if inGroup ~= wasInGroup then |
| 483 addon:ForceRefreshZone() | 596 addon:RefreshZone(true) |
| 484 wasInGroup = inGroup | 597 wasInGroup = inGroup |
| 485 addon:UpdateAutoButtonStatus() | 598 addon:UpdateAutoButtonStatus() |
| 486 end | 599 end |
| 487 end | 600 end |
| 488 | 601 |
| 495 addon:UnregisterEvent("PLAYER_REGEN_ENABLED") | 608 addon:UnregisterEvent("PLAYER_REGEN_ENABLED") |
| 496 scanstate = 0 | 609 scanstate = 0 |
| 497 addon:ScanRealm(); | 610 addon:ScanRealm(); |
| 498 end | 611 end |
| 499 | 612 |
| 500 function addon:ForceRefreshZone() | 613 function addon:RefreshZoneAndClearHistory() |
| 614 ClearRealmHistory() | |
| 501 addon:RefreshZone(true) | 615 addon:RefreshZone(true) |
| 502 end | 616 end |
| 503 | 617 |
| 504 function addon:RefreshZone(shedule) | 618 function addon:RefreshZone(shedule) |
| 505 local inst, instType = IsInInstance() | 619 local inst, instType = IsInInstance() |
| 586 lbRealm:SetText("Unknown realm (No players)") | 700 lbRealm:SetText("Unknown realm (No players)") |
| 587 return; | 701 return; |
| 588 end | 702 end |
| 589 | 703 |
| 590 local bestRealm = curRealmStat[1] | 704 local bestRealm = curRealmStat[1] |
| 705 addon:RealmVisited(bestRealm.realm, true) | |
| 591 local prevThreshold = math.min(bestRealm.count/3,10) | 706 local prevThreshold = math.min(bestRealm.count/3,10) |
| 592 local mixCount = 0 | 707 local mixCount = 0 |
| 593 for i=2,curRealmStat.realms do | 708 for i=2,curRealmStat.realms do |
| 594 local data = curRealmStat[i] | 709 local data = curRealmStat[i] |
| 595 if data.count >= prevThreshold then | 710 if data.count >= prevThreshold then |
| 596 mixCount = mixCount + 1 | 711 mixCount = mixCount + 1 |
| 712 addon:RealmVisited(data.realm) | |
| 597 prevThreshold = math.min(data.count/3,10) | 713 prevThreshold = math.min(data.count/3,10) |
| 598 end | 714 end |
| 599 end | 715 end |
| 600 curRealmStat.threshold = prevThreshold | 716 curRealmStat.threshold = prevThreshold |
| 601 | 717 |
| 611 | 727 |
| 612 | 728 |
| 613 | 729 |
| 614 -- Auto action button | 730 -- Auto action button |
| 615 | 731 |
| 616 local action; | 732 local action |
| 617 | 733 |
| 618 local function CancelJoin() | 734 local LeaveGroup = { |
| 619 local apps = C_LFGList.GetApplications(); | 735 func = LeaveParty; |
| 620 if apps[1] then | 736 tooltip = "Leave current joined group", |
| 621 C_LFGList.CancelApplication(apps[1]) | 737 text = "Leave group" |
| 622 end | 738 } |
| 623 end | 739 |
| 624 | 740 local CancelJoin = { |
| 625 local function findGroupToJoin() | 741 func = function() |
| 626 local count, list = C_LFGList.GetSearchResults() | 742 local apps = C_LFGList.GetApplications(); |
| 627 local tableData = {} | 743 if apps[1] then |
| 628 for i = 1,count do | 744 C_LFGList.CancelApplication(apps[1]) |
| 629 local rid = list[i]; | 745 end |
| 630 if not rid then break end | 746 end, |
| 631 local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rid) | 747 tooltip = "Cancel your current join application", |
| 632 | 748 text = "Cancel join" |
| 633 local data = list[i]; | 749 } |
| 634 local cols = {} | 750 |
| 635 local row = {rid} | 751 local QuickJoin = { |
| 636 cols[1] = {value=updateGroupName,args=row} | 752 func = function(self, button) |
| 637 cols[2] = {value=updateGroupCount,args=row} | 753 if button == "RightButton" then |
| 638 cols[3] = {value=updateGroupRealm,args=row} | 754 addon:SetGroupJoinStatus(self.groupToJoin, "_skip") |
| 639 cols[4] = {} | 755 else |
| 640 table.insert(tableData, {cols=cols,id=rid}) | 756 local delisted = select(11, C_LFGList.GetSearchResultInfo(self.groupToJoin)) |
| 641 | 757 if delisted == false then |
| 642 end | 758 JoinGroup(self.groupToJoin) |
| 643 end | 759 else |
| 644 | 760 addon:SetStatus("Group just delisted") |
| 645 local function QuickJoin() | 761 end |
| 646 | 762 end |
| 647 end | 763 end, |
| 648 | 764 findGroup = function() |
| 649 function addon:DoAutoAction() | 765 local count, list = C_LFGList.GetSearchResults() |
| 650 if action then action() end | 766 local best |
| 767 local bestvalue = 0 | |
| 768 for i = 1,count do | |
| 769 local rid = list[i]; | |
| 770 if not rid then break end | |
| 771 local value = WeightLfgItem(rid, true); | |
| 772 if value > bestvalue then | |
| 773 best = rid | |
| 774 bestvalue = value | |
| 775 end | |
| 776 end | |
| 777 return best | |
| 778 end, | |
| 779 tooltip = function(self) | |
| 780 AddLfgGroupInfo(self.groupToJoin, true) | |
| 781 GameTooltip:AddLine(" ") | |
| 782 GameTooltip:AddDoubleLine("Click to join","Right click to skip",0,1,0,1,0.5,0) | |
| 783 end, | |
| 784 text = "Quick join" | |
| 785 } | |
| 786 | |
| 787 local ScanNext = { | |
| 788 func = function(self) | |
| 789 autoScanGroups[curLfgGroup] = 1 | |
| 790 addon.LfgScan(self.category) | |
| 791 end, | |
| 792 tooltip = function(self) | |
| 793 GameTooltip:AddLine("Scan "..(C_LFGList.GetCategoryInfo(lfgGroups[self.category]))) | |
| 794 end, | |
| 795 text = "Scan more" | |
| 796 } | |
| 797 | |
| 798 local NeedReset = { | |
| 799 func = function() | |
| 800 wipe(autoScanGroups); | |
| 801 local categoryToScan = addon.GetNextAutoScanCategory() | |
| 802 if categoryToScan then | |
| 803 addon.LfgScan(categoryToScan) | |
| 804 end | |
| 805 end, | |
| 806 tooltip = "Scan again", | |
| 807 text = "Restart scan" | |
| 808 } | |
| 809 | |
| 810 local Wait = { | |
| 811 tooltip = "Scan in progress", | |
| 812 text = "Wait..." | |
| 813 } | |
| 814 | |
| 815 local ShowQuickHint = { | |
| 816 tooltip = "Quick Join", | |
| 817 text = "Quick Join", | |
| 818 func = function() | |
| 819 StaticPopupDialogs["CROSS_REALM_ASSIST"] = { | |
| 820 text = "Quick Join button will automatically join you to a random group with autoinvite and medium number of players. You never join same group twice, you need to clear join history to do so. This message can be disabled in options.", | |
| 821 button1 = OKAY, | |
| 822 hideOnEscape = true, | |
| 823 preferredIndex = 3, | |
| 824 } | |
| 825 StaticPopup_Show("CROSS_REALM_ASSIST") | |
| 826 hintShown = true; | |
| 827 end | |
| 828 } | |
| 829 | |
| 830 function addon.DoAutoAction(widget, button) | |
| 831 addon:SetStatus() | |
| 832 if action and action.func then | |
| 833 action:func(button) | |
| 834 end | |
| 651 addon:UpdateAutoButtonStatus() | 835 addon:UpdateAutoButtonStatus() |
| 652 end | 836 end |
| 653 | 837 |
| 838 function addon.actionTooltip() | |
| 839 local tooltip = action.tooltip | |
| 840 if type(tooltip) == 'function' then | |
| 841 tooltip(action) | |
| 842 else | |
| 843 GameTooltip:AddLine(tooltip) | |
| 844 end | |
| 845 end | |
| 846 | |
| 654 function addon:UpdateAutoButtonStatus() | 847 function addon:UpdateAutoButtonStatus() |
| 848 if not btQuick then return end | |
| 655 btQuick:Enable() | 849 btQuick:Enable() |
| 656 if IsInGroup() then | 850 if not hintShown and db.global.quickJoinHint then |
| 657 action = LeaveParty; | 851 action = ShowQuickHint; |
| 658 btQuick:SetText("Leave group") | 852 elseif IsInGroup() then |
| 853 action = LeaveGroup; | |
| 659 elseif C_LFGList.GetNumApplications() > 0 then | 854 elseif C_LFGList.GetNumApplications() > 0 then |
| 660 action = CancelJoin; | 855 action = CancelJoin; |
| 661 btQuick:SetText("Cancel join") | 856 elseif lfgScanInProgress then |
| 857 action = Wait | |
| 662 else | 858 else |
| 663 if inInstance then btQuick:Disable() end | 859 local group = QuickJoin.findGroup(); |
| 664 btQuick:SetText("Quick join") | 860 if group then |
| 665 end | 861 action = QuickJoin; |
| 666 end | 862 QuickJoin.groupToJoin = group |
| 863 else | |
| 864 local categoryToScan = addon.GetNextAutoScanCategory() | |
| 865 if (categoryToScan) then | |
| 866 action = ScanNext; | |
| 867 ScanNext.category = categoryToScan | |
| 868 else | |
| 869 action = NeedReset; | |
| 870 end | |
| 871 end | |
| 872 end | |
| 873 btQuick:SetText(action.text) | |
| 874 if GameTooltip:GetOwner() == btQuick then | |
| 875 ShowTooltip(btQuick) | |
| 876 end | |
| 877 end | |
| 878 | |
| 879 | |
| 880 | |
| 881 | |
| 882 | |
| 883 | |
| 884 -- Settings | |
| 885 | |
| 886 local function toggleMinimapIcon(btn, arg1, arg2, checked) | |
| 887 local hidden = not checked; | |
| 888 db.global.minimap.hide = hidden; | |
| 889 if hidden then | |
| 890 DEFAULT_CHAT_FRAME:AddMessage("|cffff0000Type |cffffffff/cra |cffff0000in chat to open Cross Realm Assist without minimap button"); | |
| 891 minimapIcon:Hide("CrossRealmAssistMinimapIcon") | |
| 892 else | |
| 893 minimapIcon:Show("CrossRealmAssistMinimapIcon") | |
| 894 end | |
| 895 end | |
| 896 | |
| 897 local function toggleQuickJoinHint(btn, arg1, arg2, checked) | |
| 898 db.global.quickJoinHint = checked | |
| 899 end | |
| 900 | |
| 901 local function toggleQuickJoin(btn, arg1, arg2, checked) | |
| 902 db.global.quickJoin[arg1] = checked | |
| 903 end | |
| 904 | |
| 905 local function ClearJoinHistory() | |
| 906 recentgroups = {} | |
| 907 addon:UpdateAutoButtonStatus() | |
| 908 if lfgTable then lfgTable:Refresh() end | |
| 909 end | |
| 910 | |
| 911 --[[local function resetPos() | |
| 912 db.global.widgetPos = DefaultWidgetPos | |
| 913 if gui then | |
| 914 gui:ClearAllPoints() | |
| 915 gui:SetPoint(DefaultWidgetPos.to,DefaultWidgetPos.x,DefaultWidgetPos.y) | |
| 916 end | |
| 917 end]] | |
| 918 | |
| 919 local function initMenu(self, level) | |
| 920 if not level then return end | |
| 921 if level == 1 then | |
| 922 UIDropDownMenu_AddButton({text="Clear realm history",notCheckable=1,func=ClearRealmHistory}, level) | |
| 923 UIDropDownMenu_AddButton({text="Clear join history",notCheckable=1,func=ClearJoinHistory}, level) | |
| 924 UIDropDownMenu_AddButton({disabled=1,notCheckable=1}, level) | |
| 925 UIDropDownMenu_AddButton({isTitle=1,text="Settings",notCheckable=1}, level) | |
| 926 UIDropDownMenu_AddButton({text="Show Minimap Button",checked=not db.global.minimap.hide, func=toggleMinimapIcon,keepShownOnClick=true,isNotRadio=true}, level) | |
| 927 UIDropDownMenu_AddButton({text="Show Quick Join Hint",checked=db.global.quickJoinHint, func=toggleQuickJoinHint,keepShownOnClick=true,isNotRadio=true}, level) | |
| 928 UIDropDownMenu_AddButton({text="Quick join categories",notCheckable=1,hasArrow=1,value="qjc",keepShownOnClick=true}, level) | |
| 929 elseif level == 2 then | |
| 930 if UIDROPDOWNMENU_MENU_VALUE == "qjc" then | |
| 931 for i=1,#lfgGroups do | |
| 932 local groupId = lfgGroups[i] | |
| 933 UIDropDownMenu_AddButton({text=(C_LFGList.GetCategoryInfo(groupId)),checked=db.global.quickJoin[groupId],arg1=groupId,func=toggleQuickJoin,keepShownOnClick=true,isNotRadio=true}, level) | |
| 934 end | |
| 935 end | |
| 936 end | |
| 937 end | |
| 938 | |
| 939 function addon.ShowSettings(frame) | |
| 940 if not settingsMenu then | |
| 941 settingsMenu = CreateFrame("Frame", "CrossRealmAssistMenu") | |
| 942 settingsMenu.displayMode = "MENU" | |
| 943 settingsMenu.initialize = initMenu | |
| 944 end | |
| 945 ToggleDropDownMenu(1, nil, settingsMenu, frame, 10, 0) | |
| 946 end |
