Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2018
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.31 KB | None | 0 0
  1.  
  2. local _, AltManager = ...;
  3.  
  4. _G["AltManager"] = AltManager;
  5.  
  6. -- Made by: Qooning - Tarren Mill <Method>, 2017
  7.  
  8. --local sizey = 200;
  9. local sizey = 220;
  10. local instances_y_add = 100;
  11. local xoffset = 0;
  12. local yoffset = 150;
  13. local alpha = 1;
  14. local addon = "MethodAltManager";
  15. local numel = table.getn;
  16.  
  17. local per_alt_x = 120;
  18.  
  19. local min_x_size = 300;
  20.  
  21. local min_level = 110;
  22. local name_label = "Name"
  23. local mythic_done_label = "Highest M+ done"
  24. local mythic_keystone_label = "Keystone"
  25. local seals_owned_label = "Seals owned"
  26. local seals_bought_label = "Seals obtained"
  27. local artifact_reaserch_label = "AK level"
  28. local artifact_research_time_label = "Next level in"
  29. local depleted_label = "Depleted"
  30. local nightbane_label = "Nightbane"
  31. local resources_label = "Order Resources"
  32. local argunite_label = "Veiled Argunite"
  33. local wakening_label = "Wakening Essence"
  34.  
  35. -- deprecated
  36. local max_ak = 40
  37.  
  38. local VERSION = "1.2"
  39.  
  40. -- C_ChallengeMode.GetMapTable
  41. --local dungeons = {[1501] = "BRH",
  42. -- [1571] = "CoS",
  43. -- [1466] = "DHT",
  44. -- [1456] = "EoA",
  45. -- [1477] = "HoV",
  46. -- [1492] = "MoS",
  47. -- [1458] = "NL",
  48. -- [1516] = "Arcway",
  49. -- [1493] = "VotW",
  50. -- [1544] = "VH"
  51. -- };
  52.  
  53. local dungeons = {[199] = "BRH",
  54. [210] = "CoS",
  55. [198] = "DHT",
  56. [197] = "EoA",
  57. [200] = "HoV",
  58. [208] = "MoS",
  59. [206] = "NL",
  60. [209] = "Arcway",
  61. [207] = "VotW",
  62. [1544] = "VH",
  63. [227] = "L-Kara",
  64. [233] = "Cath",
  65. [234] = "U-Kara",
  66. [239] = "Seat"
  67. };
  68.  
  69.  
  70. SLASH_METHODALTMANAGER1 = "/mam";
  71. SLASH_METHODALTMANAGER2 = "/alts";
  72.  
  73. local function spairs(t, order)
  74. local keys = {}
  75. for k in pairs(t) do keys[#keys+1] = k end
  76.  
  77. if order then
  78. table.sort(keys, function(a,b) return order(t, a, b) end)
  79. else
  80. table.sort(keys)
  81. end
  82.  
  83. local i = 0
  84. return function()
  85. i = i + 1
  86. if keys[i] then
  87. return keys[i], t[keys[i]]
  88. end
  89. end
  90. end
  91.  
  92. function SlashCmdList.METHODALTMANAGER(cmd, editbox)
  93. local rqst, arg = strsplit(' ', cmd)
  94. if rqst == "purge" then
  95. AltManager:Purge();
  96. elseif rqst == "remove" then
  97. AltManager:RemoveCharactersByName(arg)
  98. else
  99. AltManager:ShowInterface();
  100. end
  101. end
  102.  
  103. do
  104. local main_frame = CreateFrame("frame", "AltManagerFrame", UIParent);
  105. AltManager.main_frame = main_frame;
  106. main_frame:SetFrameStrata("MEDIUM");
  107. main_frame.background = main_frame:CreateTexture(nil, "BACKGROUND");
  108. main_frame.background:SetAllPoints();
  109. main_frame.background:SetDrawLayer("ARTWORK", 1);
  110. main_frame.background:SetColorTexture(0, 0, 0, 0.5);
  111.  
  112. main_frame.scan_tooltip = CreateFrame('GameTooltip', 'DepletedTooltipScan', UIParent, 'GameTooltipTemplate');
  113.  
  114.  
  115. -- Set frame position
  116. main_frame:ClearAllPoints();
  117. main_frame:SetPoint("CENTER", UIParent, "CENTER", xoffset, yoffset);
  118.  
  119. main_frame:RegisterEvent("ADDON_LOADED");
  120. main_frame:RegisterEvent("PLAYER_LOGIN");
  121. main_frame:RegisterEvent("PLAYER_LOGOUT");
  122. main_frame:RegisterEvent("QUEST_TURNED_IN");
  123. main_frame:RegisterEvent("BAG_UPDATE_DELAYED");
  124. main_frame:RegisterEvent("ARTIFACT_XP_UPDATE");
  125. main_frame:RegisterEvent("CHAT_MSG_CURRENCY");
  126. main_frame:RegisterEvent("CURRENCY_DISPLAY_UPDATE");
  127.  
  128.  
  129. main_frame:SetScript("OnEvent", function(self, ...)
  130. local event, loaded = ...;
  131. if event == "ADDON_LOADED" then
  132. if addon == loaded then
  133. AltManager:OnLoad();
  134. end
  135. end
  136. if event == "PLAYER_LOGIN" then
  137. AltManager:OnLogin();
  138. end
  139. if event == "PLAYER_LOGOUT" or event == "ARTIFACT_XP_UPDATE" then
  140. local data = AltManager:CollectData();
  141. AltManager:StoreData(data);
  142. end
  143. if (event == "BAG_UPDATE_DELAYED" or event == "QUEST_TURNED_IN" or event == "CHAT_MSG_CURRENCY" or event == "CURRENCY_DISPLAY_UPDATE") and AltManager.addon_loaded then
  144. local data = AltManager:CollectData(false);
  145. AltManager:StoreData(data);
  146. end
  147.  
  148. end)
  149.  
  150. -- Show Frame
  151. main_frame:Hide();
  152. end
  153.  
  154. function AltManager:InitDB()
  155. local t = {};
  156. t.alts = 0;
  157. return t;
  158. end
  159.  
  160. -- because of guid...
  161. function AltManager:OnLogin()
  162. self:ValidateReset();
  163. self:StoreData(self:CollectData());
  164.  
  165. local alts = MethodAltManagerDB.alts;
  166.  
  167. self.main_frame:SetSize(max((alts + 1) * per_alt_x, min_x_size), sizey);
  168. self.main_frame.background:SetAllPoints();
  169.  
  170. -- Create menus
  171.  
  172. AltManager:CreateMenu();
  173. AltManager:MakeTopBottomTextures(self.main_frame);
  174. AltManager:MakeBorder(self.main_frame, 5);
  175. end
  176.  
  177. function AltManager:OnLoad()
  178. self.main_frame:UnregisterEvent("ADDON_LOADED");
  179.  
  180. MethodAltManagerDB = MethodAltManagerDB or self:InitDB();
  181.  
  182. self.addon_loaded = true
  183. end
  184.  
  185. function AltManager:CreateFontFrame(parent, x_size, height, relative_to, y_offset, label, justify)
  186. local f = CreateFrame("Button", nil, parent);
  187. f:SetSize(x_size, height);
  188. f:SetNormalFontObject(GameFontHighlightSmall)
  189. f:SetText(label)
  190. f:SetPoint("TOPLEFT", relative_to, "TOPLEFT", 0, y_offset);
  191. f:GetFontString():SetJustifyH(justify);
  192. f:GetFontString():SetJustifyV("CENTER");
  193. f:SetPushedTextOffset(0, 0);
  194. f:GetFontString():SetWidth(120)
  195. f:GetFontString():SetHeight(20)
  196.  
  197. return f;
  198. end
  199.  
  200. function AltManager:Keyset()
  201. local keyset = {}
  202. if MethodAltManagerDB and MethodAltManagerDB.data then
  203. for k in pairs(MethodAltManagerDB.data) do
  204. table.insert(keyset, k)
  205. end
  206. end
  207. return keyset
  208. end
  209.  
  210. function AltManager:ValidateReset()
  211. local db = MethodAltManagerDB
  212. if not db then return end;
  213. if not db.data then return end;
  214.  
  215. local keyset = {}
  216. for k in pairs(db.data) do
  217. table.insert(keyset, k)
  218. end
  219.  
  220. for alt = 1, db.alts do
  221. local expiry = db.data[keyset[alt]].expires or 0;
  222. local char_table = db.data[keyset[alt]];
  223. if time() > expiry then
  224. -- reset this alt
  225. char_table.seals_bought = 0;
  226. char_table.dungeon = "Unknown";
  227. char_table.level = "?";
  228. char_table.highest_mplus = 0;
  229. char_table.is_depleted = false;
  230. char_table.expires = self:GetNextWeeklyResetTime();
  231.  
  232. char_table.nh_normal = 0;
  233. char_table.nh_heroic = 0;
  234. char_table.nh_mythic = 0;
  235. char_table.en_normal = 0;
  236. char_table.en_heroic = 0;
  237. char_table.en_mythic = 0;
  238. char_table.tov_normal = 0;
  239. char_table.tov_heroic = 0;
  240. char_table.tov_mythic = 0;
  241. char_table.tos_normal = 0;
  242. char_table.tos_heroic = 0;
  243. char_table.tos_mythic = 0;
  244. char_table.antorus_normal = 0;
  245. char_table.antorus_heroic = 0;
  246. char_table.antorus_mythic = 0;
  247.  
  248. char_table.nh_lfr = 0;
  249. char_table.en_lfr = 0;
  250. char_table.tov_lfr = 0;
  251. char_table.tos_lfr = 0;
  252. char_table.antorus_lfr = 0;
  253. end
  254. end
  255. end
  256.  
  257. function AltManager:Purge()
  258. MethodAltManagerDB = self:InitDB();
  259. end
  260.  
  261. function AltManager:RemoveCharactersByName(name)
  262. local db = MethodAltManagerDB;
  263.  
  264. local indices = {};
  265. for guid, data in pairs(db.data) do
  266. if db.data[guid].name == name then
  267. indices[#indices+1] = guid
  268. end
  269. end
  270.  
  271. db.alts = db.alts - #indices;
  272. for i = 1,#indices do
  273. db.data[indices[i]] = nil
  274. end
  275.  
  276. print("Found " .. (#indices) .. " characters by the name of " .. name)
  277. print("Please reload ui to update the displayed info.")
  278.  
  279. -- things wont be redrawn
  280. end
  281.  
  282. function AltManager:StoreData(data)
  283.  
  284. if not self.addon_loaded then
  285. return
  286. end
  287.  
  288. -- This can happen shortly after logging in, the game doesn't know the characters guid yet
  289. if not data or not data.guid then
  290. return
  291. end
  292.  
  293. if UnitLevel('player') < min_level then return end;
  294.  
  295. local db = MethodAltManagerDB;
  296. local guid = data.guid;
  297.  
  298. db.data = db.data or {};
  299.  
  300. local update = false;
  301. for k, v in pairs(db.data) do
  302. if k == guid then
  303. update = true;
  304. end
  305. end
  306.  
  307. if not update then
  308. db.data[guid] = data;
  309. db.alts = db.alts + 1;
  310. else
  311. local lvl = db.data[guid].artifact_level;
  312. data.artifact_level = data.artifact_level or lvl;
  313. db.data[guid] = data;
  314. end
  315. end
  316.  
  317. function AltManager:CollectData(do_artifact)
  318.  
  319.  
  320. if UnitLevel('player') < min_level then return end;
  321.  
  322. if do_artifact == nil then
  323. do_artifact = true
  324. end
  325.  
  326. local name = UnitName('player')
  327. local _, class = UnitClass('player')
  328. local dungeon = nil;
  329. local expire = nil;
  330. local level = nil;
  331. local seals = nil;
  332. local seals_bought = nil;
  333. local artifact_level = nil;
  334. local next_research = nil;
  335. local highest_mplus = 0;
  336. local depleted = false;
  337.  
  338. local guid = UnitGUID('player');
  339.  
  340. local mine_old = nil
  341. if MethodAltManagerDB and MethodAltManagerDB.data then
  342. mine_old = MethodAltManagerDB.data[guid];
  343. end
  344.  
  345. for k,v in pairs(dungeons) do
  346. C_ChallengeMode.RequestMapInfo(k);
  347. local _, t, l = C_ChallengeMode.GetMapPlayerStats(k);
  348. if l and l > highest_mplus then
  349. highest_mplus = l;
  350. end
  351. end
  352.  
  353. -- find keystone
  354. local keystone_found = false;
  355. for container=BACKPACK_CONTAINER, NUM_BAG_SLOTS do
  356. local slots = GetContainerNumSlots(container)
  357. for slot=1, slots do
  358. local _, _, _, _, _, _, slotLink, _, _, slotItemID = GetContainerItemInfo(container, slot)
  359. if slotItemID == 138019 then
  360. local itemString = slotLink:match("|Hkeystone:([0-9:]+)|h(%b[])|h")
  361. local info = { strsplit(":", itemString) }
  362. -- scan tooltip for depleted
  363. self.main_frame.scan_tooltip:SetOwner(UIParent, 'ANCHOR_NONE');
  364. self.main_frame.scan_tooltip:SetBagItem(container, slot);
  365. local regions = self.main_frame.scan_tooltip:GetRegions();
  366. for i = 1, self.main_frame.scan_tooltip:NumLines() do
  367. local left = _G["DepletedTooltipScanTextLeft"..i]:GetText();
  368. if string.find(left, depleted_label) then
  369. depleted = true
  370. end
  371. end
  372. self.main_frame.scan_tooltip:Hide();
  373. --local mapname = C_ChallengeMode.GetMapInfo(info[1]);
  374. dungeon = tonumber(info[1])
  375. if not dungeon then print("MethodAltManager - Parse Failure, please let Qoning know that this happened."); end
  376. level = tonumber(info[2])
  377. if not level then print("MethodAltManager - Parse Failure, please let Qoning know that this happened."); end
  378. expire = tonumber(info[10])
  379. keystone_found = true;
  380. end
  381. end
  382. end
  383. if not keystone_found then
  384. dungeon = "Unknown";
  385. level = "?"
  386. end
  387.  
  388. if do_artifact and HasArtifactEquipped() then
  389. if not ArtifactFrame then
  390. LoadAddOn("Blizzard_ArtifactUI");
  391. end
  392. -- open artifact
  393. local is_open = ArtifactFrame:IsShown();
  394. if (not ArtifactFrame or not ArtifactFrame:IsShown()) then
  395. SocketInventoryItem(INVSLOT_MAINHAND);
  396. end
  397. artifact_level = C_ArtifactUI.GetArtifactKnowledgeLevel()
  398. -- close artifact
  399. if not is_open and ArtifactFrame and ArtifactFrame:IsShown() and C_ArtifactUI.IsViewedArtifactEquipped() then
  400. C_ArtifactUI.Clear();
  401. end
  402. end
  403.  
  404. -- order resources
  405. local _, order_resources = GetCurrencyInfo(1220);
  406. local _, veiled_argunite = GetCurrencyInfo(1508);
  407. local _, wakening_essence = GetCurrencyInfo(1533);
  408.  
  409. local shipments = C_Garrison.GetLooseShipments(LE_GARRISON_TYPE_7_0)
  410. local creation_time = nil
  411. local duration = nil
  412. local num_ready = nil
  413. local num_total = nil
  414. local found_research = false
  415.  
  416. for i = 1, #shipments do
  417. local name, _, _, numReady, numTotal, creationTime, duration_l = C_Garrison.GetLandingPageShipmentInfoByContainerID(shipments[i])
  418.  
  419. if name == GetItemInfo(139390) then -- the name must be "Artifact Research Notes"
  420. found_research = true;
  421. creation_time = creationTime
  422. duration = duration_l
  423. num_ready = numReady
  424. num_total = numTotal
  425. end
  426. end
  427.  
  428.  
  429. if found_research and num_ready == 0 then
  430. local remaining = (creation_time + duration) - time();
  431. if (remaining < 0) then -- next shipment is ready
  432. num_ready = num_ready + 1
  433. if num_ready > num_total then -- prevent overflow
  434. num_ready = num_total
  435. end
  436. remaining = 0
  437. end
  438. next_research = creation_time + duration
  439. else
  440. next_research = 0;
  441. end
  442.  
  443. _, seals = GetCurrencyInfo(1273);
  444.  
  445. seals_bought = 0
  446. local gold_1 = IsQuestFlaggedCompleted(43895)
  447. if gold_1 then seals_bought = seals_bought + 1 end
  448. local gold_2 = IsQuestFlaggedCompleted(43896)
  449. if gold_2 then seals_bought = seals_bought + 1 end
  450. local gold_3 = IsQuestFlaggedCompleted(43897)
  451. if gold_3 then seals_bought = seals_bought + 1 end
  452. local resources_1 = IsQuestFlaggedCompleted(43892)
  453. if resources_1 then seals_bought = seals_bought + 1 end
  454. local resources_2 = IsQuestFlaggedCompleted(43893)
  455. if resources_2 then seals_bought = seals_bought + 1 end
  456. local resources_3 = IsQuestFlaggedCompleted(43894)
  457. if resources_3 then seals_bought = seals_bought + 1 end
  458. local marks_1 = IsQuestFlaggedCompleted(47851)
  459. if marks_1 then seals_bought = seals_bought + 1 end
  460. local marks_2 = IsQuestFlaggedCompleted(47864)
  461. if marks_2 then seals_bought = seals_bought + 1 end
  462. local marks_3 = IsQuestFlaggedCompleted(47865)
  463. if marks_3 then seals_bought = seals_bought + 1 end
  464.  
  465.  
  466. local class_hall_seal = IsQuestFlaggedCompleted(43510)
  467. if class_hall_seal then seals_bought = seals_bought + 1 end
  468.  
  469.  
  470. local nh_lfr, nh_normal, nh_heroic, nh_mythic = 0;
  471. local tov_lfr, tov_normal, tov_heroic, tov_mythic = 0;
  472. local en_lfr, en_normal, en_heroic, en_mythic = 0;
  473. local tos_lfr, tos_normal, tos_heroic, tos_mythic = 0;
  474. local antorus_lfr, antorus_normal, antorus_heroic, antorus_mythic = 0;
  475.  
  476. local nightbane_save = false;
  477. local saves = GetNumSavedInstances();
  478. for i = 1, saves do
  479. local name, _, reset, _, _, _, _, _, _, difficulty, bosses, killed_bosses = GetSavedInstanceInfo(i);
  480. -- nightbane
  481. if name == GetMapNameByID(1100) and reset > 0 then
  482. for j = 1, 20 do
  483. local boss, _, killed = GetSavedInstanceEncounterInfo(i, j);
  484. if boss == "Nightbane" then
  485. nightbane_save = killed;
  486. end
  487. end
  488. end
  489. -- check for raids
  490. if name == GetMapNameByID(1094) and reset > 0 then
  491. if difficulty == "Normal" then en_normal = killed_bosses end
  492. if difficulty == "Heroic" then en_heroic = killed_bosses end
  493. if difficulty == "Mythic" then en_mythic = killed_bosses end
  494. end
  495. if name == GetMapNameByID(1114) and reset > 0 then
  496. if difficulty == "Normal" then tov_normal = killed_bosses end
  497. if difficulty == "Heroic" then tov_heroic = killed_bosses end
  498. if difficulty == "Mythic" then tov_mythic = killed_bosses end
  499. end
  500. if name == GetMapNameByID(1088) and reset > 0 then
  501. if difficulty == "Normal" then nh_normal = killed_bosses end
  502. if difficulty == "Heroic" then nh_heroic = killed_bosses end
  503. if difficulty == "Mythic" then nh_mythic = killed_bosses end
  504. end
  505. if name == GetMapNameByID(1147) and reset > 0 then
  506. if difficulty == "Normal" then tos_normal = killed_bosses end
  507. if difficulty == "Heroic" then tos_heroic = killed_bosses end
  508. if difficulty == "Mythic" then tos_mythic = killed_bosses end
  509. end
  510. if name == GetMapNameByID(1188) and reset > 0 then
  511. if difficulty == "Normal" then antorus_normal = killed_bosses end
  512. if difficulty == "Heroic" then antorus_heroic = killed_bosses end
  513. if difficulty == "Mythic" then antorus_mythic = killed_bosses end
  514. end
  515. end
  516.  
  517. local nh_lfr_id = {1293, 1292, 1291, 1290};
  518. local tov_lfr_id = {1411};
  519. local en_lfr_id = {1288, 1287, 1289};
  520. local tos_lfr_id = {1494, 1495, 1496, 1497};
  521. local antorus_lfr_id = {1610, 1611, 1612, 1613};
  522.  
  523. -- used to find: for i = 1,2000 do if(GetLFGDungeonInfo(i)) then print(i, GetLFGDungeonInfo(i)) end end
  524.  
  525. for _, v in pairs(nh_lfr_id) do
  526. local _, killed = GetLFGDungeonNumEncounters(v);
  527. nh_lfr = nh_lfr + killed;
  528. end
  529. for _, v in pairs(tov_lfr_id) do
  530. local _, killed = GetLFGDungeonNumEncounters(v);
  531. tov_lfr = tov_lfr + killed;
  532. end
  533. for _, v in pairs(en_lfr_id) do
  534. local _, killed = GetLFGDungeonNumEncounters(v);
  535. en_lfr = en_lfr + killed;
  536. end
  537. for _, v in pairs(tos_lfr_id) do
  538. local _, killed = GetLFGDungeonNumEncounters(v);
  539. tos_lfr = tos_lfr + killed;
  540. end
  541. for _, v in pairs(antorus_lfr_id) do
  542. local _, killed = GetLFGDungeonNumEncounters(v);
  543. antorus_lfr = antorus_lfr + killed;
  544. end
  545.  
  546.  
  547. local _, ilevel = GetAverageItemLevel();
  548.  
  549. -- store data into a table
  550.  
  551. local char_table = {}
  552.  
  553. char_table.guid = UnitGUID('player');
  554. char_table.name = name;
  555. char_table.class = class;
  556. char_table.ilevel = ilevel;
  557. char_table.seals = seals;
  558. char_table.seals_bought = seals_bought;
  559.  
  560. if mine_old and mine_old.next_research and mine_old.next_research > next_research then
  561. char_table.next_research = mine_old.next_research;
  562. elseif mine_old and mine_old.next_research and mine_old.next_research < next_research then
  563. char_table.next_research = next_research;
  564. print("MethodAltManager debug: trying to overwrite old value with a lower one!");
  565. else
  566. char_table.next_research = next_research;
  567. end
  568. if do_artifact then
  569. char_table.artifact_level = artifact_level;
  570. end
  571. char_table.dungeon = dungeon;
  572. char_table.level = level;
  573. char_table.highest_mplus = highest_mplus;
  574. --remove nightbane for now
  575. --char_table.nightbane = nightbane_save;
  576.  
  577. char_table.nh_lfr = nh_lfr;
  578. char_table.en_lfr = en_lfr;
  579. char_table.tov_lfr = tov_lfr;
  580. char_table.tos_lfr = tos_lfr;
  581. char_table.antorus_lfr = antorus_lfr;
  582.  
  583. char_table.nh_normal = nh_normal;
  584. char_table.nh_heroic = nh_heroic;
  585. char_table.nh_mythic = nh_mythic;
  586. char_table.en_normal = en_normal;
  587. char_table.en_heroic = en_heroic;
  588. char_table.en_mythic = en_mythic;
  589. char_table.tov_normal = tov_normal;
  590. char_table.tov_heroic = tov_heroic;
  591. char_table.tov_mythic = tov_mythic;
  592. char_table.tos_normal = tos_normal;
  593. char_table.tos_heroic = tos_heroic;
  594. char_table.tos_mythic = tos_mythic;
  595. char_table.antorus_normal = antorus_normal;
  596. char_table.antorus_heroic = antorus_heroic;
  597. char_table.antorus_mythic = antorus_mythic;
  598.  
  599. char_table.order_resources = order_resources;
  600. char_table.veiled_argunite = veiled_argunite;
  601. char_table.wakening_essence = wakening_essence;
  602. char_table.is_depleted = depleted;
  603. char_table.expires = self:GetNextWeeklyResetTime();
  604.  
  605.  
  606. return char_table;
  607. end
  608.  
  609. function AltManager:PopulateStrings()
  610. local font_height = 20;
  611. local db = MethodAltManagerDB;
  612.  
  613. local keyset = {}
  614. for k in pairs(db.data) do
  615. table.insert(keyset, k)
  616. end
  617.  
  618. self.main_frame.alt_columns = self.main_frame.alt_columns or {};
  619.  
  620. local alt = 0
  621. for alt_guid, alt_data in spairs(db.data, function(t, a, b) return t[a].ilevel > t[b].ilevel end) do
  622. alt = alt + 1
  623. -- create the frame to which all the fontstrings anchor
  624. local anchor_frame = self.main_frame.alt_columns[alt] or CreateFrame("Button", nil, self.main_frame);
  625. if not self.main_frame.alt_columns[alt] then
  626. self.main_frame.alt_columns[alt] = anchor_frame;
  627. end
  628. anchor_frame:SetPoint("TOPLEFT", self.main_frame, "TOPLEFT", per_alt_x * alt, -1);
  629. anchor_frame:SetSize(per_alt_x, sizey);
  630. -- init table for fontstring storage
  631. self.main_frame.alt_columns[alt].label_columns = self.main_frame.alt_columns[alt].label_columns or {};
  632. local label_columns = self.main_frame.alt_columns[alt].label_columns;
  633. -- create / fill fontstrings
  634. local i = 1;
  635. for column_iden, column in spairs(self.columns_table, function(t, a, b) return t[a].order < t[b].order end) do
  636. -- only display data with values
  637. if type(column.data) == "function" then
  638. local current_row = label_columns[i] or self:CreateFontFrame(self.main_frame, per_alt_x, column.font_height or font_height, anchor_frame, -(i - 1) * font_height, column.data(alt_data), "CENTER");
  639. -- insert it into storage if just created
  640. if not self.main_frame.alt_columns[alt].label_columns[i] then
  641. self.main_frame.alt_columns[alt].label_columns[i] = current_row;
  642. end
  643. if column.color then
  644. local color = column.color(alt_data)
  645. current_row:GetFontString():SetTextColor(color.r, color.g, color.b, 1);
  646. end
  647. current_row:SetText(column.data(alt_data))
  648. if column.font then
  649. current_row:GetFontString():SetFont(column.font, 8)
  650. else
  651. --current_row:GetFontString():SetFont("Fonts\\FRIZQT__.TTF", 14)
  652. end
  653. if column.justify then
  654. current_row:GetFontString():SetJustifyV(column.justify);
  655. end
  656. end
  657. i = i + 1
  658. end
  659.  
  660. end
  661.  
  662. end
  663.  
  664. function AltManager:CreateMenu()
  665.  
  666. -- Close button
  667. self.main_frame.closeButton = CreateFrame("Button", "CloseButton", self.main_frame, "UIPanelCloseButton");
  668. self.main_frame.closeButton:ClearAllPoints()
  669. self.main_frame.closeButton:SetPoint("BOTTOMRIGHT", self.main_frame, "TOPRIGHT", -10, -2);
  670. self.main_frame.closeButton:SetScript("OnClick", function() AltManager:HideInterface(); end);
  671. --self.main_frame.closeButton:SetSize(32, h);
  672.  
  673. local column_table = {
  674. name = {
  675. order = 1,
  676. label = name_label,
  677. data = function(alt_data) return alt_data.name end,
  678. color = function(alt_data) return RAID_CLASS_COLORS[alt_data.class] end,
  679. },
  680. ilevel = {
  681. order = 2,
  682. data = function(alt_data) return string.format("%.2f", alt_data.ilevel or 0) end,
  683. justify = "TOP",
  684. font = "Fonts\\FRIZQT__.TTF",
  685. },
  686. mplus = {
  687. order = 3,
  688. label = mythic_done_label,
  689. data = function(alt_data) return tostring(alt_data.highest_mplus) end,
  690. },
  691. keystone = {
  692. order = 4,
  693. label = mythic_keystone_label,
  694. data = function(alt_data) local depleted_string = alt_data.is_depleted and " (D)" or ""; return (dungeons[alt_data.dungeon] or alt_data.dungeon) .. " +" .. tostring(alt_data.level) .. depleted_string; end,
  695. },
  696. seals_owned = {
  697. order = 5,
  698. label = seals_owned_label,
  699. data = function(alt_data) return tostring(alt_data.seals) end,
  700. },
  701. seals_bought = {
  702. order = 6,
  703. label = seals_bought_label,
  704. data = function(alt_data) return tostring(alt_data.seals_bought) end,
  705. },
  706. --artifact_level = {
  707. -- order = 7,
  708. -- label = artifact_reaserch_label,
  709. -- data = function(alt_data) return tostring(alt_data.artifact_level) end,
  710. --},
  711. --next_research = {
  712. -- order = 8,
  713. -- label = artifact_research_time_label,
  714. -- data = function(alt_data) local remaining = alt_data.next_research - time(); if remaining < 0 then remaining = 0; end return alt_data.artifact_level < max_ak and self:TimeString(remaining) or "Max" end,
  715. --},
  716. order_resources = {
  717. order = 9,
  718. label = resources_label,
  719. data = function(alt_data) return alt_data.order_resources and tostring(alt_data.order_resources) or "0" end,
  720. },
  721. veiled_argunite = {
  722. order = 9.5,
  723. label = argunite_label,
  724. data = function(alt_data) return alt_data.veiled_argunite and tostring(alt_data.veiled_argunite) or "0" end,
  725. },
  726. wakening_essence = {
  727. order = 9.6,
  728. label = wakening_label,
  729. data = function(alt_data) return alt_data.wakening_essence and tostring(alt_data.wakening_essence) or "0" end,
  730. },
  731. dummy_empty_line = {
  732. order = 10,
  733. data = function(alt_data) return " " end,
  734. },
  735. raid_unroll = {
  736. order = 11,
  737. data = "unroll",
  738. name = "Instances >>",
  739. unroll_function = function(button, my_rows)
  740. self.instances_unroll = self.instances_unroll or {};
  741. self.instances_unroll.state = self.instances_unroll.state or "closed";
  742. if self.instances_unroll.state == "closed" then
  743. -- do unroll
  744. self.instances_unroll.unroll_frame = self.instances_unroll.unroll_frame or CreateFrame("Button", nil, self.main_frame);
  745. self.instances_unroll.unroll_frame:SetSize(per_alt_x, instances_y_add);
  746. self.instances_unroll.unroll_frame:SetPoint("TOPLEFT", self.main_frame, "TOPLEFT", 4, self.main_frame.lowest_point - 10);
  747. self.instances_unroll.unroll_frame:Show();
  748.  
  749. local font_height = 20;
  750. -- create the rows for the unroll
  751. if not self.instances_unroll.labels then
  752. self.instances_unroll.labels = {};
  753. local i = 1
  754. for row_iden, row in spairs(my_rows, function(t, a, b) return t[a].order < t[b].order end) do
  755. if row.label then
  756. local label_row = self:CreateFontFrame(self.instances_unroll.unroll_frame, per_alt_x, font_height, self.instances_unroll.unroll_frame, -(i-1)*font_height, row.label..":", "RIGHT");
  757. table.insert(self.instances_unroll.labels, label_row)
  758. end
  759. i = i + 1
  760. end
  761. end
  762.  
  763. -- populate it for alts
  764. self.instances_unroll.alt_columns = self.instances_unroll.alt_columns or {};
  765. local alt = 0
  766. local db = MethodAltManagerDB;
  767. for alt_guid, alt_data in spairs(db.data, function(t, a, b) return t[a].ilevel > t[b].ilevel end) do
  768. alt = alt + 1
  769. -- create the frame to which all the fontstrings anchor
  770. local anchor_frame = self.instances_unroll.alt_columns[alt] or CreateFrame("Button", nil, self.instances_unroll.unroll_frame);
  771. if not self.instances_unroll.alt_columns[alt] then
  772. self.instances_unroll.alt_columns[alt] = anchor_frame;
  773. end
  774. anchor_frame:SetPoint("TOPLEFT", self.instances_unroll.unroll_frame, "TOPLEFT", per_alt_x * alt, -1);
  775. anchor_frame:SetSize(per_alt_x, instances_y_add);
  776. -- init table for fontstring storage
  777. self.instances_unroll.alt_columns[alt].label_columns = self.instances_unroll.alt_columns[alt].label_columns or {};
  778. local label_columns = self.instances_unroll.alt_columns[alt].label_columns;
  779. -- create / fill fontstrings
  780. local i = 1;
  781. for column_iden, column in spairs(my_rows, function(t, a, b) return t[a].order < t[b].order end) do
  782. local current_row = label_columns[i] or self:CreateFontFrame(self.instances_unroll.unroll_frame, per_alt_x, column.font_height or font_height, anchor_frame, -(i - 1) * font_height, column.data(alt_data), "CENTER");
  783. -- insert it into storage if just created
  784. if not self.instances_unroll.alt_columns[alt].label_columns[i] then
  785. self.instances_unroll.alt_columns[alt].label_columns[i] = current_row;
  786. end
  787. current_row:SetText(column.data(alt_data))
  788. i = i + 1
  789. end
  790. end
  791.  
  792. -- fixup the background
  793. self.main_frame:SetSize(max((alt + 1) * per_alt_x, min_x_size), sizey + instances_y_add);
  794. self.main_frame.background:SetAllPoints();
  795.  
  796. button:SetText("Instances <<");
  797. self.instances_unroll.state = "open";
  798. else
  799. -- do rollup
  800. self.main_frame:SetSize(max((MethodAltManagerDB.alts + 1) * per_alt_x, min_x_size), sizey);
  801. self.main_frame.background:SetAllPoints();
  802. self.instances_unroll.unroll_frame:Hide();
  803. button:SetText("Instances >>");
  804. self.instances_unroll.state = "closed";
  805. end
  806. end,
  807. rows = {
  808. tomb_of_sargeras = {
  809. order = 1,
  810. label = "Tomb of Sargeras",
  811. data = function(alt_data) return self:MakeRaidString(alt_data.tos_lfr, alt_data.tos_normal, alt_data.tos_heroic, alt_data.tos_mythic) end
  812. },
  813. nighthold = {
  814. order = 2,
  815. label = "Nighthold",
  816. data = function(alt_data) return self:MakeRaidString(alt_data.nh_lfr, alt_data.nh_normal, alt_data.nh_heroic, alt_data.nh_mythic) end
  817. },
  818. trial_of_valor = {
  819. order = 3,
  820. label = "Trial of Valor",
  821. data = function(alt_data) return self:MakeRaidString(alt_data.tov_lfr, alt_data.tov_normal, alt_data.tov_heroic, alt_data.tov_mythic) end
  822. },
  823. emerald_nightmare = {
  824. order = 4,
  825. label = "Emerald Nightmare",
  826. data = function(alt_data) return self:MakeRaidString(alt_data.en_lfr, alt_data.en_normal, alt_data.en_heroic, alt_data.en_mythic) end
  827. },
  828. antorus_raid = {
  829. order = 0.5,
  830. label = "Antorus",
  831. data = function(alt_data) return self:MakeRaidString(alt_data.antorus_lfr, alt_data.antorus_normal, alt_data.antorus_heroic, alt_data.antorus_mythic) end
  832. }
  833. }
  834. }
  835. }
  836. self.columns_table = column_table;
  837.  
  838. -- create labels and unrolls
  839. local font_height = 20;
  840. local label_column = self.main_frame.label_column or CreateFrame("Button", nil, self.main_frame);
  841. if not self.main_frame.label_column then self.main_frame.label_column = label_column; end
  842. label_column:SetSize(per_alt_x, sizey);
  843. label_column:SetPoint("TOPLEFT", self.main_frame, "TOPLEFT", 4, -1);
  844.  
  845. local i = 1;
  846. for row_iden, row in spairs(self.columns_table, function(t, a, b) return t[a].order < t[b].order end) do
  847. if row.label then
  848. local label_row = self:CreateFontFrame(self.main_frame, per_alt_x, font_height, label_column, -(i-1)*font_height, row.label..":", "RIGHT");
  849. self.main_frame.lowest_point = -(i-1)*font_height;
  850. end
  851. if row.data == "unroll" then
  852. -- create a button that will unroll it
  853. local unroll_button = CreateFrame("Button", "UnrollButton", self.main_frame, "UIPanelButtonTemplate");
  854. unroll_button:SetText(row.name);
  855. unroll_button:SetFrameStrata("HIGH");
  856. --unroll_button:SetFrameLevel(self.main_frame:GetFrameLevel() - 1);
  857. unroll_button:SetSize(unroll_button:GetTextWidth() + 20, 25);
  858. unroll_button:SetPoint("BOTTOMRIGHT", self.main_frame, "TOPLEFT", 4 + per_alt_x, -(i-1)*font_height-10);
  859. unroll_button:SetScript("OnClick", function() row.unroll_function(unroll_button, row.rows) end);
  860. self.main_frame.lowest_point = -(i-1)*font_height-10;
  861. end
  862. i = i + 1
  863. end
  864.  
  865. end
  866.  
  867. function AltManager:MakeRaidString(lfr, normal, heroic, mythic)
  868. if not normal then normal = 0 end
  869. if not heroic then heroic = 0 end
  870. if not mythic then mythic = 0 end
  871. if not lfr then lfr = 0 end
  872. local string = ""
  873. if mythic > 0 then string = string .. tostring(mythic) .. "M" end
  874. if heroic > 0 and mythic > 0 then string = string .. "-" end
  875. if heroic > 0 then string = string .. tostring(heroic) .. "H" end
  876. if normal > 0 and (mythic > 0 or heroic > 0) then string = string .. "-" end
  877. if normal > 0 then string = string .. tostring(normal) .. "N" end
  878. if lfr > 0 and (mythic > 0 or heroic > 0 or normal > 0) then string = string .. "-" end
  879. if lfr > 0 then string = string .. tostring(lfr) .. "L" end
  880. return string == "" and "-" or string
  881. end
  882.  
  883. function AltManager:HideInterface()
  884. self.main_frame:Hide();
  885. end
  886.  
  887. function AltManager:ShowInterface()
  888. self.main_frame:Show();
  889. self:StoreData(self:CollectData())
  890. self:PopulateStrings();
  891. end
  892.  
  893. function AltManager:MakeTopBottomTextures(frame)
  894. if frame.bottomPanel == nil then
  895. frame.bottomPanel = frame:CreateTexture(nil);
  896. end
  897. if frame.topPanel == nil then
  898. frame.topPanel = CreateFrame("Frame", "AltManagerTopPanel", frame);
  899. frame.topPanelTex = frame.topPanel:CreateTexture(nil, "BACKGROUND");
  900. --frame.topPanelTex:ClearAllPoints();
  901. frame.topPanelTex:SetAllPoints();
  902. --frame.topPanelTex:SetSize(frame:GetWidth(), 30);
  903. frame.topPanelTex:SetDrawLayer("ARTWORK", -5);
  904. frame.topPanelTex:SetColorTexture(0, 0, 0, 0.7);
  905.  
  906. frame.topPanelString = frame.topPanel:CreateFontString("Method name");
  907. frame.topPanelString:SetFont("Fonts\\FRIZQT__.TTF", 20)
  908. frame.topPanelString:SetTextColor(1, 1, 1, 1);
  909. frame.topPanelString:SetJustifyH("CENTER")
  910. frame.topPanelString:SetJustifyV("CENTER")
  911. frame.topPanelString:SetWidth(260)
  912. frame.topPanelString:SetHeight(20)
  913. frame.topPanelString:SetText("Method Alt Manager");
  914. frame.topPanelString:ClearAllPoints();
  915. frame.topPanelString:SetPoint("CENTER", frame.topPanel, "CENTER", 0, 0);
  916. frame.topPanelString:Show();
  917.  
  918. end
  919. frame.bottomPanel:SetColorTexture(0, 0, 0, 0.7);
  920. frame.bottomPanel:ClearAllPoints();
  921. frame.bottomPanel:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, 0);
  922. frame.bottomPanel:SetSize(frame:GetWidth(), 30);
  923. frame.bottomPanel:SetDrawLayer("ARTWORK", 7);
  924.  
  925. frame.topPanel:ClearAllPoints();
  926. frame.topPanel:SetSize(frame:GetWidth(), 30);
  927. frame.topPanel:SetPoint("BOTTOMLEFT", frame, "TOPLEFT", 0, 0);
  928.  
  929. frame:SetMovable(true);
  930. frame.topPanel:EnableMouse(true);
  931. frame.topPanel:RegisterForDrag("LeftButton");
  932. frame.topPanel:SetScript("OnDragStart", function(self,button)
  933. frame:SetMovable(true);
  934. frame:StartMoving();
  935. end);
  936. frame.topPanel:SetScript("OnDragStop", function(self,button)
  937. frame:StopMovingOrSizing();
  938. frame:SetMovable(false);
  939. end);
  940. end
  941.  
  942. function AltManager:MakeBorderPart(frame, x, y, xoff, yoff, part)
  943. if part == nil then
  944. part = frame:CreateTexture(nil);
  945. end
  946. part:SetTexture(0, 0, 0, 1);
  947. part:ClearAllPoints();
  948. part:SetPoint("TOPLEFT", frame, "TOPLEFT", xoff, yoff);
  949. part:SetSize(x, y);
  950. part:SetDrawLayer("ARTWORK", 7);
  951. return part;
  952. end
  953.  
  954. function AltManager:MakeBorder(frame, size)
  955. if size == 0 then
  956. return;
  957. end
  958. frame.borderTop = self:MakeBorderPart(frame, frame:GetWidth(), size, 0, 0, frame.borderTop); -- top
  959. frame.borderLeft = self:MakeBorderPart(frame, size, frame:GetHeight(), 0, 0, frame.borderLeft); -- left
  960. frame.borderBottom = self:MakeBorderPart(frame, frame:GetWidth(), size, 0, -frame:GetHeight() + size, frame.borderBottom); -- bottom
  961. frame.borderRight = self:MakeBorderPart(frame, size, frame:GetHeight(), frame:GetWidth() - size, 0, frame.borderRight); -- right
  962. end
  963.  
  964. -- shamelessly stolen from saved instances
  965. function AltManager:GetNextWeeklyResetTime()
  966. if not self.resetDays then
  967. local region = self:GetRegion()
  968. if not region then return nil end
  969. self.resetDays = {}
  970. self.resetDays.DLHoffset = 0
  971. if region == "US" then
  972. self.resetDays["2"] = true -- tuesday
  973. -- ensure oceanic servers over the dateline still reset on tues UTC (wed 1/2 AM server)
  974. self.resetDays.DLHoffset = -3
  975. elseif region == "EU" then
  976. self.resetDays["3"] = true -- wednesday
  977. elseif region == "CN" or region == "KR" or region == "TW" then -- XXX: codes unconfirmed
  978. self.resetDays["4"] = true -- thursday
  979. else
  980. self.resetDays["2"] = true -- tuesday?
  981. end
  982. end
  983. local offset = (self:GetServerOffset() + self.resetDays.DLHoffset) * 3600
  984. local nightlyReset = self:GetNextDailyResetTime()
  985. if not nightlyReset then return nil end
  986. while not self.resetDays[date("%w",nightlyReset+offset)] do
  987. nightlyReset = nightlyReset + 24 * 3600
  988. end
  989. return nightlyReset
  990. end
  991.  
  992. function AltManager:GetNextDailyResetTime()
  993. local resettime = GetQuestResetTime()
  994. if not resettime or resettime <= 0 or -- ticket 43: can fail during startup
  995. -- also right after a daylight savings rollover, when it returns negative values >.<
  996. resettime > 24*3600+30 then -- can also be wrong near reset in an instance
  997. return nil
  998. end
  999. if false then -- this should no longer be a problem after the 7.0 reset time changes
  1000. -- ticket 177/191: GetQuestResetTime() is wrong for Oceanic+Brazilian characters in PST instances
  1001. local serverHour, serverMinute = GetGameTime()
  1002. local serverResetTime = (serverHour*3600 + serverMinute*60 + resettime) % 86400 -- GetGameTime of the reported reset
  1003. local diff = serverResetTime - 10800 -- how far from 3AM server
  1004. if math.abs(diff) > 3.5*3600 -- more than 3.5 hours - ignore TZ differences of US continental servers
  1005. and self:GetRegion() == "US" then
  1006. local diffhours = math.floor((diff + 1800)/3600)
  1007. resettime = resettime - diffhours*3600
  1008. if resettime < -900 then -- reset already passed, next reset
  1009. resettime = resettime + 86400
  1010. elseif resettime > 86400+900 then
  1011. resettime = resettime - 86400
  1012. end
  1013. end
  1014. end
  1015. return time() + resettime
  1016. end
  1017.  
  1018. function AltManager:GetServerOffset()
  1019. local serverDay = CalendarGetDate() - 1 -- 1-based starts on Sun
  1020. local localDay = tonumber(date("%w")) -- 0-based starts on Sun
  1021. local serverHour, serverMinute = GetGameTime()
  1022. local localHour, localMinute = tonumber(date("%H")), tonumber(date("%M"))
  1023. if serverDay == (localDay + 1)%7 then -- server is a day ahead
  1024. serverHour = serverHour + 24
  1025. elseif localDay == (serverDay + 1)%7 then -- local is a day ahead
  1026. localHour = localHour + 24
  1027. end
  1028. local server = serverHour + serverMinute / 60
  1029. local localT = localHour + localMinute / 60
  1030. local offset = floor((server - localT) * 2 + 0.5) / 2
  1031. return offset
  1032. end
  1033.  
  1034. function AltManager:GetRegion()
  1035. if not self.region then
  1036. local reg
  1037. reg = GetCVar("portal")
  1038. if reg == "public-test" then -- PTR uses US region resets, despite the misleading realm name suffix
  1039. reg = "US"
  1040. end
  1041. if not reg or #reg ~= 2 then
  1042. local gcr = GetCurrentRegion()
  1043. reg = gcr and ({ "US", "KR", "EU", "TW", "CN" })[gcr]
  1044. end
  1045. if not reg or #reg ~= 2 then
  1046. reg = (GetCVar("realmList") or ""):match("^(%a+)%.")
  1047. end
  1048. if not reg or #reg ~= 2 then -- other test realms?
  1049. reg = (GetRealmName() or ""):match("%((%a%a)%)")
  1050. end
  1051. reg = reg and reg:upper()
  1052. if reg and #reg == 2 then
  1053. self.region = reg
  1054. end
  1055. end
  1056. return self.region
  1057. end
  1058.  
  1059. function AltManager:GetWoWDate()
  1060. local hour = tonumber(date("%H"));
  1061. local day = CalendarGetDate();
  1062. return day, hour;
  1063. end
  1064.  
  1065. function AltManager:TimeString(length)
  1066. if length == 0 then
  1067. return "Now";
  1068. end
  1069. if length < 3600 then
  1070. return string.format("%d mins", length / 60);
  1071. end
  1072. if length < 86400 then
  1073. return string.format("%d hrs %d mins", length / 3600, (length % 3600) / 60);
  1074. end
  1075. return string.format("%d days %d hrs", length / 86400, (length % 86400) / 3600);
  1076. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement