Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2017
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.69 KB | None | 0 0
  1. /* ***********************************
  2. *** Copyright (c) 2017 bruk
  3. *** This script is free software; you can redistribute it and/or modify
  4. *** it under the terms of the GNU General Public License as published by
  5. *** the Free Software Foundation; either version 3 of the License, or
  6. *** (at your option) any later version.
  7. ***
  8. *** Want to keep up to date or suggest modifications to this script?
  9. *** then hop on over to http://twitter.com/bruk
  10.  
  11. ** SHOUT OUTS / THANKS TO CONTRIBUTORS:
  12. ** /u/InABohx for massive overhauls to the gem system, help with the final part of the legendary quest, tons of other stuff
  13. ** /u/jethryn for the awesome job getting the new legendary quest milestone IDs
  14. ** /u/Kiingzy for enchant id numbers which helped greatly with the audit
  15. ** all the folks on twitter and reddit who have suggested such great features
  16.  
  17. ************************************* */
  18.  
  19.  
  20. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORTANT!!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  21. // You need to put your api key here, inside the quotes
  22. // Request one here: https://dev.battle.net/apps/register
  23. // Step by step instructions: http://bruk.org/api
  24. var apikey = "wd3f989w7y4js9gmvsxzr42ppxmuskye";
  25.  
  26.  
  27. // Change this to the threshold you want to start checking for epic gems (ie: if it's 709 anything 710 or above will be checked for epic gems)
  28. var CONST_EPICGEM_ILVL = 860;
  29.  
  30. // You shouldn't need to change this, but this is threshold item level where gear is checked for enchants and gems
  31. var CONST_AUDIT_ILVL = 599;
  32.  
  33. // Set this to be the minimum iLvl of the current raid's tier gear (helps weed out the tier column noise)
  34. var CONST_TIER_GEAR_ILVL = 860;
  35.  
  36. //If you want total AP gathered displayed next to highest weapon rank, change this to true
  37. var showTotalArtifactPower = false;
  38.  
  39. //If you want Legendary items to be marked with a + next to item level (use conditional formatting to change their color) change this to true
  40.  
  41. var markLegendary = false;
  42.  
  43. // Everything below this, you shouldn't have to edit
  44. //***************************************************************
  45. /* globals Utilities, UrlFetchApp, Logger */
  46. /* exported wow, vercheck */
  47.  
  48. var current_version = 3.22;
  49.  
  50.  
  51. function relic(equippedRelic)
  52. {
  53. var id = equippedRelic.itemId;
  54.  
  55. if (id == 140070)
  56. {
  57. return "Frost +45 ilvls";
  58. }
  59.  
  60. var bonusLists = "";
  61. equippedRelic.bonusLists.forEach(function(bonusListNumber)
  62. {
  63. bonusLists = bonusLists + bonusListNumber + ",";
  64. });
  65. Utilities.sleep(500);
  66. var relicDat = "";
  67. var relicJSON ="";
  68. {
  69. try
  70. {
  71. relicJSON = UrlFetchApp.fetch("https://us.api.battle.net/wow/item/"+id+"?bl="+bonusLists+"&locale=en_US&apikey="+apikey+"");
  72. relicDat = JSON.parse(relicJSON.toString());
  73. }
  74. catch (e)
  75. {
  76. Logger.log("Error Fetching: "+ e.message);
  77. }
  78. Logger.log(relicDat);
  79. }
  80.  
  81. var elementType = relicDat.gemInfo.type.type;
  82.  
  83. if (elementType === "WIND") //Fixing a bug on Blizzard's end for the storm relic
  84. {
  85. elementType = "STORM";
  86. }
  87.  
  88. var ilvl = relicDat.itemLevel;
  89.  
  90. //@Corazu: ilvl is wonky for lower level where they aren't necessarily on increments of 5. 3 rounds down, 8 rounds up
  91. //the data is collected via item links in game to get the right +ilvl bonus for each ilvl of relic. The data may be incomplete
  92. //for certain increments that aren't 5, even with the rounding, as there are gaps in between the 5 increments where the +ilvl
  93. //bonus jumps by more than 1, leaving room for say, a xx8 to be in the middle.
  94. //At some point for posterity I'll probably come back and fix those cases, but it's a lot of manual work to hand-check all the values
  95. if (ilvl%5!=0)
  96. {
  97. var spare = ilvl%10;
  98. if (spare<=3)
  99. {
  100. ilvl-=spare;
  101. }
  102. else
  103. {
  104. ilvl+=(5-spare);
  105. }
  106.  
  107. }
  108.  
  109. var relicIlvl = 0;
  110. if (ilvl<=690)
  111. {
  112. relicIlvl = 2; //anything less than this adds 2
  113. }
  114. else
  115. {
  116. switch (ilvl)
  117. {
  118. case (695): relicIlvl="3"; break;
  119. case (700): relicIlvl="4"; break;
  120. case (705): relicIlvl="5"; break;
  121. case (710): relicIlvl="7"; break;
  122. case (715): relicIlvl="8"; break;
  123. case (720): relicIlvl="9"; break;
  124. case (725): relicIlvl="10"; break;
  125. case (730): relicIlvl="12"; break;
  126. case (735): relicIlvl="13"; break;
  127. case (740): relicIlvl="14"; break;
  128. case (745): relicIlvl="15"; break;
  129. case (750): relicIlvl="17"; break;
  130. case (755): relicIlvl="18"; break;
  131. case (760): relicIlvl="19"; break;
  132. case (765): relicIlvl="21"; break;
  133. case (770): relicIlvl="22"; break;
  134. case (775): relicIlvl="23"; break;
  135. case (780): relicIlvl="24"; break;
  136. case (785): relicIlvl="26"; break;
  137. case (790): relicIlvl="27"; break;
  138. case (795): relicIlvl="28"; break;
  139. case (800): relicIlvl="29"; break;
  140. case (805): relicIlvl="31"; break;
  141. case (810): relicIlvl="32"; break;
  142. case (815): relicIlvl="33"; break;
  143. case (820): relicIlvl="35"; break;
  144. case (825): relicIlvl="36"; break;
  145. case (830): relicIlvl="37"; break;
  146. case (835): relicIlvl="39"; break;
  147. case (840): relicIlvl="40"; break;
  148. case (845): relicIlvl="42"; break;
  149. case (850): relicIlvl="43"; break;
  150. case (855): relicIlvl="45"; break;
  151. case (860): relicIlvl="46"; break;
  152. case (865): relicIlvl="48"; break;
  153. case (870): relicIlvl="49"; break;
  154. case (875): relicIlvl="51"; break;
  155. case (880): relicIlvl="52"; break;
  156. case (885): relicIlvl="53"; break;
  157. case (890): relicIlvl="55"; break;
  158. case (895): relicIlvl="56"; break;
  159. case (900): relicIlvl="58"; break;
  160. case (905): relicIlvl="59"; break;
  161. case (910): relicIlvl="61"; break;
  162. case (915): relicIlvl="62"; break;
  163. case (920): relicIlvl="64"; break;
  164. case (925): relicIlvl="65"; break;
  165. case (930): relicIlvl="66"; break;
  166. case (935): relicIlvl="68"; break;
  167. case (940): relicIlvl="70"; break;
  168. case (945): relicIlvl="71"; break;
  169. case (950): relicIlvl="72"; break;
  170. case (955): relicIlvl="73"; break;
  171. case (960): relicIlvl="75"; break;
  172. default: relicIlvl="75+";
  173. }
  174. }
  175. return elementType+" +"+relicIlvl+" ilvls";
  176. }
  177.  
  178. function rep(standing)
  179. {
  180.  
  181. switch (standing)
  182. {
  183. case 0:
  184. return "Hated";
  185.  
  186. case 1:
  187. return "Hostile";
  188.  
  189. case 2:
  190. return "Unfriendly";
  191.  
  192. case 3:
  193. return "Neutral";
  194.  
  195. case 4:
  196. return "Friendly";
  197.  
  198. case 5:
  199. return "Honored";
  200.  
  201. case 6:
  202. return "Revered";
  203.  
  204. case 7:
  205. return "Exalted";
  206.  
  207. default:
  208. return "ERROR";
  209. }
  210. }
  211.  
  212. //thanks to github user bloodrash for this function
  213. function numberWithCommas(x)
  214. {
  215. return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  216. }
  217.  
  218.  
  219. function wow(region,toonName,realmName)
  220. {
  221.  
  222. if (!toonName || !realmName)
  223. {
  224. return " "; // If there's nothing in the column, don't even bother calling the API
  225. }
  226.  
  227. if (!apikey)
  228. {
  229. return "Error: No API key entered. Please visit http://dev.battle.net/ to obtain one. Instructions availible at http://bruk.org/wow";
  230. }
  231.  
  232.  
  233. Utilities.sleep(Math.floor((Math.random() * 10000) + 1000)); // This is a random sleepy time so that we dont spam the api and get bonked with an error
  234.  
  235. //Getting rid of any sort of pesky no width white spaces we may run into
  236. toonName = toonName.replace(/[\u200B-\u200D\uFEFF]/g, "");
  237. region = region.replace(/[\u200B-\u200D\uFEFF]/g, "");
  238. realmName = realmName.replace(/[\u200B-\u200D\uFEFF]/g, "");
  239.  
  240. region = region.toLowerCase(); // if we don't do this, it screws up the avatar display 9_9
  241.  
  242. var options={ muteHttpExceptions:true };
  243. var toon = "";
  244.  
  245. while (!toon.name) //try again because of these frequent timeouts
  246. {
  247. try
  248. {
  249. var toonJSON = UrlFetchApp.fetch("https://"+region+".api.battle.net/wow/character/"+realmName+"/"+toonName+"?fields=reputation,statistics,items,quests,achievements,audit,progression,feed,professions,talents&?locale=en_US&apikey="+apikey+"", options);
  250. toon = JSON.parse(toonJSON.toString());
  251. }
  252. catch (e)
  253. {
  254. Logger.log("Error Fetching: "+ e.message);
  255. }
  256. Logger.log(toonJSON);
  257. }
  258.  
  259. var mainspec = "none";
  260. for (var i = 0; i < 4; i++)
  261. {
  262. if (toon.talents[i].selected === true)
  263. {
  264. mainspec=toon.talents[i].spec.name;
  265. }
  266. }
  267.  
  268. // figuring out what the class is
  269. var toon_class = 0;
  270.  
  271. switch (toon.class)
  272. {
  273. case 1:
  274. toon_class = "Warrior";
  275. break;
  276. case 2:
  277. toon_class = "Paladin";
  278. break;
  279. case 3:
  280. toon_class = "Hunter";
  281. break;
  282. case 4:
  283. toon_class = "Rogue";
  284. break;
  285. case 5:
  286. toon_class = "Priest";
  287. break;
  288. case 6:
  289. toon_class = "DeathKnight";
  290. break;
  291. case 7:
  292. toon_class = "Shaman";
  293. break;
  294. case 8:
  295. toon_class = "Mage";
  296. break;
  297. case 9:
  298. toon_class = "Warlock";
  299. break;
  300. case 10:
  301. toon_class = "Monk";
  302. break;
  303. case 11:
  304. toon_class = "Druid";
  305. break;
  306. case 12:
  307. toon_class = "Demon Hunter";
  308. break;
  309. default:
  310. toon_class = "?";
  311. }
  312.  
  313.  
  314. // Time to do some gear audits
  315. var auditInfo ="";
  316.  
  317. var totalGems = [0, 0, 0, 0];
  318.  
  319. var gemAudit = [
  320. { bool: 0, issue: " Old:" },
  321. { bool: 0, issue: " Cheap:" },
  322. { bool: 0, issue: " No Prime Stat Epic" }, // this was a list of non-epic gems, when they weren't unique
  323. { bool: 0, issue: " Mixed Gems" }
  324. ];
  325.  
  326. var gemStats = [
  327. { value: 0, stat: "Crit" },
  328. { value: 0, stat: "Haste" },
  329. { value: 0, stat: "Vers" },
  330. { value: 0, stat: "Mast" },
  331. { value: 0, stat: "Str" },
  332. { value: 0, stat: "Agi" },
  333. { value: 0, stat: "Int" },
  334. { value: 0, stat: "Crit" }, //look, this is gonna be weird.. but it's for the new epic gems which are weirdly numbered and different from previous order
  335. { value: 0, stat: "-" },
  336. { value: 0, stat: "-" },
  337. { value: 0, stat: "Haste" },
  338. { value: 0, stat: "Mast" },
  339. { value: 0, stat: "Vers" },
  340. ];
  341.  
  342.  
  343. // I love me some look up tables! These are to check if you have a crappy enchant or gem
  344. var audit_lookup = {};
  345.  
  346. //cheap enchants and gems
  347.  
  348. //ring
  349. audit_lookup["5423"] = "Word +150C";
  350. audit_lookup["5424"] = "Word +150H";
  351. audit_lookup["5425"] = "Word +150M";
  352. audit_lookup["5426"] = "Word +150V";
  353. //cloak
  354. audit_lookup["5431"] = "Word +150S";
  355. audit_lookup["5432"] = "Word +150A";
  356. audit_lookup["5433"] = "Word +150I";
  357. //gems
  358. audit_lookup["130218"] =
  359. audit_lookup["130217"] =
  360. audit_lookup["130216"] =
  361. audit_lookup["130215"] = 0;
  362.  
  363. //better enchants and gems
  364.  
  365. //ring
  366. audit_lookup["5427"] = "Binding +200C";
  367. audit_lookup["5428"] = "Binding +200H";
  368. audit_lookup["5429"] = "Binding +200M";
  369. audit_lookup["5430"] = "Binding +200V";
  370.  
  371. //cloak
  372. audit_lookup["5434"] = "Binding +200S";
  373. audit_lookup["5435"] = "Binding +200A";
  374. audit_lookup["5436"] = "Binding +200I";
  375.  
  376. //gems
  377. audit_lookup["130219"] =
  378. audit_lookup["130220"] =
  379. audit_lookup["130221"] =
  380. audit_lookup["130222"] =1;
  381.  
  382. //epic gems
  383. audit_lookup["130246"] = //strengh
  384. audit_lookup["130247"] = //agility
  385. audit_lookup["130248"] = 2; //Int
  386.  
  387. // NEW epic gems
  388. audit_lookup["151580"] =
  389. audit_lookup["151583"] =
  390. audit_lookup["151584"] =
  391. audit_lookup["151585"] = 3;
  392.  
  393. //neck
  394. audit_lookup["5437"] = "Claw";
  395. audit_lookup["5438"] = "Army";
  396. audit_lookup["5439"] = "Satyr";
  397. audit_lookup["5889"] = "Hide";
  398. audit_lookup["5890"] = "Soldier";
  399. audit_lookup["5891"] = "Priestess";
  400.  
  401.  
  402. audit_lookup["5895"] = "Master";
  403. audit_lookup["5896"] = "Versatile";
  404. audit_lookup["5897"] = "Quick";
  405. audit_lookup["5898"] = "Deadly";
  406.  
  407.  
  408. //shoulder
  409. audit_lookup["5440"] = "Scavenger (cloth)";
  410. audit_lookup["5441"] = "Gemfinder";
  411. audit_lookup["5442"] = "Harvester (herbs/fish)";
  412. audit_lookup["5443"] = "Butcher (leather/meat)";
  413. audit_lookup["5882"] = "Manaseeker (enchant)";
  414. audit_lookup["5881"] = "Salvager (ore/armor)";
  415. audit_lookup["5883"] = "Bloodhunter (Blood)";
  416. audit_lookup["5900"] = "Zookeeper (Pet)";
  417. audit_lookup["5888"] = "Netherdrift";
  418. audit_lookup["5899"] = "Builder (Engineer)";
  419.  
  420.  
  421. //gloves
  422. audit_lookup["5444"] = "Herb";
  423. audit_lookup["5445"] = "Mine";
  424. audit_lookup["5446"] = "Skin";
  425. audit_lookup["5447"] = "Survey";
  426.  
  427. var thumbnail = "http://render-"+region+".worldofwarcraft.com/character/"+ toon.thumbnail;
  428. var armory = "http://"+region+".battle.net/wow/en/character/"+realmName+"/"+toonName+"/advanced";
  429.  
  430. var tier = " ";
  431. var tier_pieces = [toon.items.head,toon.items.shoulder,toon.items.chest,toon.items.hands,toon.items.legs,toon.items.back];
  432.  
  433. var set1 = [];
  434. var set2 = [];
  435.  
  436. //var gemMatch = 0; //check if our rare/uncommon gems match
  437.  
  438. for (i = 0; i < tier_pieces.length; i++)
  439. {
  440. if (tier_pieces[i] && tier_pieces[i].tooltipParams.set && tier_pieces[i].itemLevel >= CONST_TIER_GEAR_ILVL)
  441. {
  442. if (!set1.length)
  443. {
  444. set1 = tier_pieces[i].tooltipParams.set;
  445. }
  446.  
  447. if (!set2.length && set1.indexOf(tier_pieces[i].id) ==-1)
  448. {
  449. set2 = tier_pieces[i].tooltipParams.set;
  450. }
  451. }
  452. }
  453.  
  454. if (set2.length)
  455. {
  456. tier = set1.length + "/" + set2.length;
  457. }
  458. else
  459. {
  460. tier = set1.length;
  461. }
  462.  
  463. var allItems={
  464. equippedItems:0,
  465. totalIlvl:0,
  466. upgrade: {
  467. total:0,
  468. current:0
  469. }
  470. };
  471. var enchantableItems=["neck","back","finger1","finger2","hands","shoulder"];
  472. var getItemInfo = function (item, slot)
  473. {
  474. allItems[slot] = {
  475. ilvl:"\u2063",
  476. upgrade:"-"
  477. };
  478.  
  479. if (item)
  480. {
  481. if (item.tooltipParams.upgrade)
  482. {
  483. allItems[slot].upgrade= item.tooltipParams.upgrade.current + "/" + item.tooltipParams.upgrade.total;
  484. allItems.upgrade.total+=item.tooltipParams.upgrade.total;
  485. allItems.upgrade.current+=item.tooltipParams.upgrade.current;
  486. }
  487.  
  488. //crafted gear upgrade stuff
  489. var obliterum = 11; //current cap for obliterum upgrades
  490. var craftedUpgrade = -1;
  491.  
  492. for (var j = 0; j < item.bonusLists.length; j++)
  493. {
  494. switch (item.bonusLists[j])
  495. {
  496. case 596:
  497. craftedUpgrade = 0;
  498. break;
  499. case 597:
  500. craftedUpgrade = 1;
  501. break;
  502. case 598:
  503. craftedUpgrade = 2;
  504. break;
  505. case 599:
  506. craftedUpgrade = 3;
  507. break;
  508. case 666:
  509. craftedUpgrade = 4;
  510. break;
  511. case 667:
  512. craftedUpgrade = 5;
  513. break;
  514. case 668:
  515. craftedUpgrade = 6;
  516. break;
  517. case 669:
  518. craftedUpgrade = 7;
  519. break;
  520. case 670:
  521. craftedUpgrade = 8;
  522. break;
  523. case 671:
  524. craftedUpgrade = 9;
  525. break;
  526. case 672:
  527. craftedUpgrade = 10;
  528. break;
  529. default:
  530. craftedUpgrade = "-";
  531.  
  532. }
  533. }
  534.  
  535. if (craftedUpgrade > -1)
  536. {
  537. allItems[slot].upgrade= craftedUpgrade + "/" + obliterum;
  538. allItems.upgrade.total+=obliterum;
  539. allItems.upgrade.current+=craftedUpgrade;
  540. }
  541.  
  542. allItems.equippedItems++;
  543. allItems[slot].ilvl = item.itemLevel;
  544. allItems.totalIlvl += item.itemLevel;
  545.  
  546. //temporary workaround for armory still returning wrong ilvl (895 instead of 910) for legion legendaries
  547. //provided by @lifeguttter
  548. //modified to use bonuslist for 940 instead of 910
  549. /*if (item.quality == 5)
  550. {
  551. if (item.bonusLists[0] == 3529)
  552. {
  553. allItems[slot].ilvl = 940;
  554. // allItems.totalIlvl += 30; Believe this line was not needed, it was causing ilvl to be too high
  555. }
  556. }*/
  557.  
  558. if (item.quality === 5 && markLegendary)
  559. {
  560. allItems[slot].ilvl = allItems[slot].ilvl + "+"; // * can be any character you want, use it for your conditional
  561. }
  562.  
  563.  
  564. if (item.itemLevel > CONST_AUDIT_ILVL)
  565. {
  566. if (item.tooltipParams.gem0&&slot!="mainHand"&&slot!="offHand")
  567. {
  568. if (item.tooltipParams.gem0 > 151579) // new epic gems
  569. {
  570. gemStats[item.tooltipParams.gem0-151580+7].value = gemStats[item.tooltipParams.gem0-151580+7].value+200;
  571. }
  572. else if (item.tooltipParams.gem0 > 130245) //(epic) I think this could be beautified/simplifed, basically it adds to the stat value for each quality
  573. {
  574. gemStats[item.tooltipParams.gem0-130246+4].value = gemStats[item.tooltipParams.gem0-130246+4].value+200;
  575. }
  576. else if (item.tooltipParams.gem0 > 130218) //(rare)
  577. {
  578. gemStats[item.tooltipParams.gem0-130219].value = gemStats[item.tooltipParams.gem0-130219].value+150;
  579. }
  580. else if (item.tooltipParams.gem0 > 130214) //(uncommon)
  581. {
  582. gemStats[item.tooltipParams.gem0-130215].value = gemStats [item.tooltipParams.gem0-130215].value+100;
  583. }
  584.  
  585. if (item.itemLevel>CONST_EPICGEM_ILVL)
  586. {
  587. if (audit_lookup[item.tooltipParams.gem0] == 2) //this was set to != when epic gems weren't unique
  588. {
  589. gemAudit[2].bool = 0;
  590. //gemAudit[2].bool = 1;
  591. //gemAudit[2].issue += " "+ slot;
  592. }
  593. }
  594.  
  595. else if (audit_lookup[item.tooltipParams.gem0] === 0)
  596. {
  597. gemAudit[1].bool = 1;
  598. gemAudit[1].issue += " " + slot;
  599. }
  600. else if (audit_lookup[item.tooltipParams.gem0] != 1)
  601. {
  602. gemAudit[0].bool = 1;
  603. gemAudit[0].issue += " " + slot;
  604.  
  605. }
  606.  
  607. /* //Mixed Gems - if a gem is not epic, check if it has the same stat type, if so, then copy it into gemMatch to compare it to the next one
  608. if (audit_lookup[item.tooltipParams.gem0] != 2 && (gemMatch == 0 || gemMatch === item.tooltipParams.gem0 || gemMatch === item.tooltipParams.gem0+4 || gemMatch === item.tooltipParams.gem0-4))
  609. {
  610. gemMatch = item.tooltipParams.gem0;
  611. }
  612. else if (audit_lookup[item.tooltipParams.gem0] != 2 && audit_lookup[item.tooltipParams.gem0] > -1)
  613. {
  614. gemAudit[3].bool = 1; // if we fail to pass the above if, the stats don't match on our gems
  615. }*/
  616.  
  617. totalGems[audit_lookup[item.tooltipParams.gem0]]++;
  618. }
  619.  
  620. if (enchantableItems.indexOf(slot)!=-1)
  621. {
  622. allItems[slot].enchant= "None";
  623. if (item.tooltipParams.enchant)
  624. {
  625. if (audit_lookup[item.tooltipParams.enchant])
  626. {
  627. allItems[slot].enchant = audit_lookup[item.tooltipParams.enchant];
  628. }
  629. else
  630. {
  631. allItems[slot].enchant = "Old";
  632. }
  633. }
  634. }
  635. }
  636. }
  637. };
  638.  
  639. var sortOrder = [
  640. "head",
  641. "neck",
  642. "shoulder",
  643. "back",
  644. "chest",
  645. "wrist",
  646. "hands",
  647. "waist",
  648. "legs",
  649. "feet",
  650. "finger1",
  651. "finger2",
  652. "trinket1",
  653. "trinket2",
  654. "mainHand",
  655. "offHand"
  656. ];
  657.  
  658. for (i = 0; i < sortOrder.length; i++)
  659. {
  660. getItemInfo(toon.items[sortOrder[i]],sortOrder[i]);
  661. }
  662.  
  663.  
  664. //always put the higher level trinket/ring on the leftier column
  665. var bruksOCDswap = function (item1,item2)
  666. {
  667. if (allItems[item1].ilvl<allItems[item2].ilvl)
  668. {
  669. var swapValue = allItems[item1].ilvl;
  670. allItems[item1].ilvl = allItems[item2].ilvl;
  671. allItems[item2].ilvl = swapValue;
  672. }
  673. };
  674.  
  675. bruksOCDswap("finger1","finger2");
  676. bruksOCDswap("trinket1","trinket2");
  677.  
  678. // /u/orange_gauss supplied this for fixing the double weight of 2handers
  679. if (allItems.offHand.ilvl == "\u2063" )
  680. {
  681. allItems.totalIlvl += allItems.mainHand.ilvl;
  682. allItems.equippedItems += 1;
  683. }
  684.  
  685. allItems.averageIlvl = allItems.totalIlvl / allItems.equippedItems;
  686.  
  687. //fall back to max unequipped ilvl if they're currently partially nude
  688. if (isNaN(allItems.averageIlvl))
  689. {
  690. allItems.averageIlvl = toon.items.averageItemLevel;
  691. }
  692.  
  693. if (toon.audit.emptySockets !== 0)
  694. {
  695. auditInfo = auditInfo + "Empty Gem Sockets: " + toon.audit.emptySockets + " ";
  696. }
  697.  
  698.  
  699. if (totalGems[0]+totalGems[1]+totalGems[2]+totalGems[3]>0) //gems exist!
  700. {
  701. auditInfo = auditInfo + "Gems" ;
  702.  
  703. if (totalGems[0] > 0)
  704. {
  705. auditInfo = auditInfo + " UnCom:" + totalGems[0];
  706. }
  707.  
  708. if (totalGems[1] > 0)
  709. {
  710. auditInfo = auditInfo + " Rare:" + totalGems[1];
  711. }
  712.  
  713. if (totalGems[3] > 0)
  714. {
  715. auditInfo = auditInfo + " Epic:" + totalGems[3];
  716. }
  717.  
  718. if (totalGems[2] > 0)
  719. {
  720. auditInfo = auditInfo + " PrimeEpic:" + totalGems[2];
  721. }
  722.  
  723. for (i=0; i<gemStats.length; i++)
  724. {
  725. if (gemStats[i].value > 0)
  726. {
  727. auditInfo = auditInfo + " +" + gemStats[i].value + gemStats[i].stat + " ";
  728. }
  729. }
  730.  
  731. }
  732.  
  733. for (i=0; i<gemAudit.length; i++)
  734. {
  735. if (gemAudit[i].bool > 0)
  736. {
  737. auditInfo = auditInfo + gemAudit[i].issue;
  738. }
  739. }
  740.  
  741. // lock out "Weekly checker"
  742. var todayStamp =new Date();
  743. var today = todayStamp.getDay();
  744. var sinceYesterday = 0;
  745. var now = todayStamp.getHours();
  746. var resetTime = new Date();
  747.  
  748. var offset = new Date().getTimezoneOffset();
  749. offset=offset/60;
  750.  
  751. if (region == "us")
  752. {
  753. resetTime.setHours(15-offset,0,0,0);
  754. }
  755. else
  756. {
  757. resetTime.setHours(7-offset,0,0,0);
  758. }
  759.  
  760.  
  761. sinceYesterday = resetTime.getTime();
  762.  
  763.  
  764. //attempt to fix post-midnight pre-reset
  765. if (now < 15-offset && now > -1 && region == "us") //if it's after midnight but before 11am
  766. {
  767. sinceYesterday-=86400000;
  768. }
  769.  
  770. if (now < 7-offset && now > -1 && region == "eu") //if it's after midnight but before 7am
  771. {
  772. sinceYesterday-=86400000;
  773. }
  774.  
  775.  
  776. // now we have to figure out how long it's been since tuesday
  777. var sinceTuesday =new Date();
  778.  
  779. var reset = region == "eu" ? 3 : 2; // 2 for tuesday, 3 for wednesday
  780.  
  781. var midnight = new Date();
  782. midnight.setHours(0,0,0,0);
  783.  
  784. sinceTuesday = resetTime*1;
  785.  
  786. if (today == reset) //it IS tuesday!
  787. {
  788. //attempt to fix post-midnight pre-reset
  789. if ((now < 7-offset && now > -1 && region == "eu") || (now < 15-offset && now > -1 && region == "us")) //if it's after midnight but before 7am
  790. {
  791. sinceTuesday-=(86400000*7);
  792. }
  793. }
  794.  
  795. if (today > reset)
  796. {
  797. // wednesday (thurs eu) - saturday
  798. sinceTuesday = sinceTuesday-(today-reset)*86400000;
  799. }
  800.  
  801. else if (today < reset)
  802. {
  803. // sunday + monday (tues eu)
  804. sinceTuesday = sinceTuesday-((7+today-reset))*86400000; // this was 6, but to account for EU it was changed to 7-reset to be either 6 or 5 to account for Wednesday resets
  805. }
  806.  
  807. // Raid stat sub-categories
  808. var STATS_RAIDS_LEGION = 6;
  809. var raidInstancesSortOrder = [];
  810. var raidDifficultySortOrder = ["Raid Finder", "Normal", "Heroic", "Mythic"];
  811. for (i = 35; i <= 38; i++) // legion raids up to ToS increase 38 if new raid comes
  812. {
  813. raidInstancesSortOrder.push(toon.progression.raids[i].name);
  814. }
  815. var instanceDetails = { "dungeons":{},"raids":{} };
  816. for (i in raidInstancesSortOrder)
  817. {
  818. instanceDetails.raids[raidInstancesSortOrder[i]] = {};
  819. }
  820. var getShortInstanceName = function (inputString)
  821. {
  822. var split = inputString.split(" ");
  823. if (split.length !== 1)
  824. {
  825. var retstring = "";
  826. for (i in split)
  827. {
  828. retstring = retstring + split[i].slice(0, 1);
  829. }
  830. return retstring;
  831. }
  832. else
  833. {
  834. return split[0].slice(0,3).toUpperCase();
  835. }
  836. };
  837. var getRaidAndBossName = function(inputString)
  838. {
  839. var info = "";
  840.  
  841. //attempt to get boss name, raid, and difficulty by splitting based on this string
  842. if (inputString.indexOf("defeats") !== -1)
  843. {
  844. info = inputString.split(" defeats (");
  845. }
  846. else if (inputString.indexOf("redemptions") !== -1)
  847. {
  848. info = inputString.split(" redemptions (");
  849. }
  850. else if (inputString.indexOf("defenses") !== -1)
  851. {
  852. info = inputString.split(" defenses (");
  853. }
  854. else
  855. {
  856. info = inputString.split(" kills (");
  857. }
  858. var bossName = info.shift(); // first we get boss name
  859. info = info[0].split(" ");
  860. var difficultyName = "";
  861. var nameForInstance = "";
  862. if (info[0] === "Raid")
  863. {
  864. difficultyName = info.shift() + " " + info.shift(); // Raid Finder
  865. nameForInstance = info.join(" ").slice(0, -1); // rest is the name and we remove the last ")"
  866. }
  867. else if (info[0] !== "Return")
  868. {
  869. difficultyName = info.shift(); // first info is what difficultie we have
  870. nameForInstance = info.join(" ").slice(0, -1); // rest is the name and we remove the last ")"
  871. }
  872. else // this should only be Return to Karazhan
  873. {
  874. difficultyName = "Mythic";
  875. nameForInstance = info.join(" ").slice(0, -1); // rest is the name and we remove the last ")"
  876. }
  877. return [bossName, nameForInstance, difficultyName];
  878. };
  879. for (var instanceNumber in toon.statistics.subCategories[5].subCategories[STATS_RAIDS_LEGION].statistics)
  880. {
  881. var instanceBoss = toon.statistics.subCategories[5].subCategories[STATS_RAIDS_LEGION].statistics[instanceNumber];
  882. var instanceReturns = getRaidAndBossName(instanceBoss.name);
  883. var bossName = instanceReturns[0];
  884. var nameOfInstance = instanceReturns[1];
  885. var difficultyName = instanceReturns[2];
  886. var typeOfInstance = "Dungeon";
  887. for (var raid in raidInstancesSortOrder)// this is needed this as "the" is missing from instances.
  888. {
  889. if (raidInstancesSortOrder[raid].indexOf(nameOfInstance) !== -1)
  890. {
  891. nameOfInstance = raidInstancesSortOrder[raid];
  892. typeOfInstance = "Raid";
  893. }
  894. }
  895. var thisInstance = typeOfInstance === "Raid" ? instanceDetails.raids : instanceDetails.dungeons;
  896. thisInstance[nameOfInstance] = thisInstance[nameOfInstance] || {};
  897. thisInstance[nameOfInstance][difficultyName] = thisInstance[nameOfInstance][difficultyName] || {};
  898. thisInstance[nameOfInstance][difficultyName].bosses = thisInstance[nameOfInstance][difficultyName].bosses || {};
  899.  
  900. var infoForBoss = { "kills": instanceBoss.quantity };
  901. if (typeOfInstance === "Dungeon" && difficultyName === "Heroic")
  902. {
  903. infoForBoss.lockout = instanceBoss.lastUpdated > sinceYesterday;
  904. }
  905. else if (typeOfInstance !== "Dungeon" || difficultyName !== "Normal")// everything except normal dungeons
  906. {
  907. infoForBoss.lockout = instanceBoss.lastUpdated > sinceTuesday;
  908. }
  909. if (nameOfInstance.indexOf("Violet Hold")===-1)
  910. {
  911. thisInstance[nameOfInstance][difficultyName].bosses[bossName] = infoForBoss;
  912. }
  913. else
  914. {
  915. var oldInfo = thisInstance[nameOfInstance][difficultyName].bosses["Violet Hold End Boss"] || {};
  916. if (oldInfo.kills)
  917. {
  918. infoForBoss.kills += oldInfo.kills;
  919. infoForBoss.lockout = infoForBoss.lockout || oldInfo.lockout; // since 0 is false and 1 is true this will work.
  920. }
  921. thisInstance[nameOfInstance][difficultyName].bosses["Violet Hold End Boss"] = infoForBoss;
  922. }
  923. thisInstance[nameOfInstance][difficultyName].kills = thisInstance[nameOfInstance][difficultyName].kills || 0;
  924. thisInstance[nameOfInstance][difficultyName].kills += instanceBoss.quantity;
  925. }
  926. var displayInfo = { "raid": {}, "dungeon": {} };
  927. for (var instanceType in instanceDetails)
  928. {
  929. var instances = instanceDetails[instanceType];
  930. var infoOnDifficulty = {};
  931. for (var instanceName in instances)
  932. {
  933. var instance = instances[instanceName];
  934. if (instanceType === "raids") // for dungeons we take lockout for all instances, for raid we do it for each instance.
  935. {
  936. infoOnDifficulty = {};
  937. }
  938. for (var difficulty in instance)
  939. {
  940. infoOnDifficulty[difficulty] = infoOnDifficulty[difficulty] || {
  941. "activeWeeks":0, "lockout":0, "instanceLength": 0, "progress": 0, "kills": 0
  942. };
  943. var thisDifficulty = infoOnDifficulty[difficulty];
  944. var bosses = instance[difficulty].bosses;
  945. for (var boss in bosses)
  946. {
  947. var bossInfo = bosses[boss];
  948. thisDifficulty.activeWeeks = Math.max(thisDifficulty.activeWeeks, bossInfo.kills);
  949. thisDifficulty.instanceLength++;
  950. thisDifficulty.kills += bossInfo.kills;
  951. thisDifficulty.progress += bossInfo.kills === 0 ? 0 : 1;
  952. thisDifficulty.lockout += bossInfo.lockout ? 1 : 0;
  953. if (instanceType === "dungeons" && difficulty === "Mythic" && bossInfo.lockout)
  954. {
  955. thisDifficulty.details = thisDifficulty.details ? thisDifficulty.details + ", " + getShortInstanceName(instanceName) : getShortInstanceName(instanceName);
  956. }
  957. }
  958. }
  959. if (instanceType === "raids")
  960. {
  961. displayInfo.raid[instanceName] = infoOnDifficulty;
  962. }
  963. }
  964. if (instanceType === "dungeons")
  965. {
  966. displayInfo.dungeon = infoOnDifficulty;
  967. }
  968. }
  969.  
  970. var profession1 = "none";
  971. if (toon.professions.primary[0])
  972. {
  973. profession1 = toon.professions.primary[0].rank + " " + toon.professions.primary[0].name;
  974. }
  975. var profession2 = "none";
  976. if (toon.professions.primary[1])
  977. {
  978. profession2 = toon.professions.primary[1].rank + " " + toon.professions.primary[1].name;
  979. }
  980.  
  981. var upgradePercent = "-";
  982.  
  983. if (allItems.upgrade.total > 0)
  984. {
  985. upgradePercent = Math.round(allItems.upgrade.current/allItems.upgrade.total*100) + "%";
  986. }
  987.  
  988. var artifactRank = "x";
  989. var artifactRelics = [];
  990. var relicItems = ["mainHand","offHand"];
  991. var relicCount = 0;
  992.  
  993. for (i = 0; i < relicItems.length; i++)
  994. {
  995. // var k = relicItems[i] unused?
  996. if (toon.items[relicItems[i]])
  997. {
  998. var relicItem = toon.items[relicItems[i]];
  999. if (relicItem.quality > 4)
  1000. {
  1001. artifactRank = 0;
  1002. relicItem.relics.forEach(function(relicGem)
  1003. {
  1004. artifactRelics.push(relic(relicGem));
  1005. relicCount++;
  1006. });
  1007. }
  1008. }
  1009. }
  1010.  
  1011. if (toon.items.mainHand && toon.items.mainHand.quality == 6)
  1012. {
  1013. if (toon.items.mainHand.artifactTraits[0])
  1014. {
  1015. for (i=0; i<toon.items.mainHand.artifactTraits.length; i++)
  1016. {
  1017. artifactRank = artifactRank + toon.items.mainHand.artifactTraits[i].rank;
  1018. }
  1019. artifactRank = artifactRank - relicCount;
  1020. }
  1021.  
  1022. else if (toon.items.offHand.artifactTraits[0])
  1023. {
  1024. for (i=0; i<toon.items.offHand.artifactTraits.length; i++)
  1025. {
  1026. artifactRank = artifactRank + toon.items.offHand.artifactTraits[i].rank;
  1027. }
  1028. artifactRank = artifactRank - relicCount;
  1029. }
  1030. }
  1031.  
  1032.  
  1033. // this was the previous method for calculating artifactRank
  1034. /*for (i=0; i<toon.achievements.criteria.length; i++)
  1035. {
  1036. if (toon.achievements.criteria[i] == "29395")
  1037. {
  1038. artifactRank = toon.achievements.criteriaQuantity[i];
  1039. }
  1040. }*/
  1041.  
  1042.  
  1043. // IDs for mythic+ were provied by @matdemy on twitter and this post: http://us.battle.net/forums/en/bnet/topic/20752275890
  1044. var mythicPlus = "";
  1045. for (i=0; i<toon.achievements.criteria.length; i++)
  1046. {
  1047. switch (toon.achievements.criteria[i])
  1048. {
  1049. case (30103):
  1050. if (showTotalArtifactPower)
  1051. {
  1052. artifactRank = artifactRank + " | AP: " + numberWithCommas(toon.achievements.criteriaQuantity[i]);
  1053. }
  1054. break;
  1055.  
  1056. case (31466):
  1057. if (showTotalArtifactPower)
  1058. {
  1059. artifactRank = artifactRank + " | AK: " + toon.achievements.criteriaQuantity[i];
  1060. }
  1061. break;
  1062.  
  1063. case (33096):
  1064. mythicPlus = mythicPlus + "m+2: " + toon.achievements.criteriaQuantity[i];
  1065. break;
  1066.  
  1067. case (33097):
  1068. mythicPlus = mythicPlus + " m+5: " + toon.achievements.criteriaQuantity[i];
  1069. break;
  1070.  
  1071. case (33098):
  1072. mythicPlus = mythicPlus + " m+10: " + toon.achievements.criteriaQuantity[i];
  1073. break;
  1074.  
  1075. case (32028):
  1076. mythicPlus = mythicPlus + " m+15: " + toon.achievements.criteriaQuantity[i];
  1077. break;
  1078.  
  1079. default:
  1080. break;
  1081. }
  1082. }
  1083.  
  1084. for (i = artifactRelics.length; i < 3; i++)
  1085. {
  1086. artifactRelics.push("x");
  1087. }
  1088.  
  1089. var nightfallen = "";
  1090. for (i=0; i<toon.reputation.length; i++)
  1091. {
  1092. if (toon.reputation[i].id == 1859)
  1093. {
  1094. nightfallen = rep(toon.reputation[i].standing);
  1095. nightfallen = "Nightfallen - " + nightfallen + " " + toon.reputation[i].value + "/" + toon.reputation[i].max;
  1096. }
  1097. }
  1098.  
  1099. var toonStamina = toon.stats(sta);
  1100.  
  1101. var toonInfo = [
  1102.  
  1103. toon_class,
  1104. toon.level,
  1105. mainspec,
  1106. allItems.averageIlvl,
  1107. upgradePercent,
  1108. tier,
  1109.  
  1110. artifactRank,
  1111. artifactRelics[0], artifactRelics[1], artifactRelics[2],
  1112. auditInfo,
  1113.  
  1114. displayInfo.dungeon.Heroic.lockout + "/" + displayInfo.dungeon.Heroic.instanceLength,
  1115. displayInfo.dungeon.Heroic.progress + "/" + displayInfo.dungeon.Heroic.instanceLength + " (" + displayInfo.dungeon.Heroic.kills + ")",
  1116.  
  1117. displayInfo.dungeon.Mythic.lockout + "/" + displayInfo.dungeon.Mythic.instanceLength + " " + displayInfo.dungeon.Mythic.details,
  1118. displayInfo.dungeon.Mythic.progress + "/" + displayInfo.dungeon.Mythic.instanceLength + " [" + displayInfo.dungeon.Mythic.activeWeeks + "] (" + displayInfo.dungeon.Mythic.kills + ") " + mythicPlus,
  1119.  
  1120. profession1, profession2, thumbnail, armory,
  1121. allItems[enchantableItems[4]].enchant, allItems[enchantableItems[5]].enchant,
  1122. nightfallen,
  1123. ];
  1124.  
  1125. var possision = 6;
  1126. for (i = 0; i<sortOrder.length;i++)
  1127. {
  1128. toonInfo.splice(possision,0,allItems[sortOrder[i]].ilvl);
  1129. toonInfo.splice(possision+12+i,0,allItems[sortOrder[i]].upgrade);
  1130. possision++;
  1131. }
  1132. possision+=4;
  1133. for (i = 0; i < enchantableItems.length-2;i++)
  1134. {
  1135. toonInfo.splice(possision,0,allItems[enchantableItems[i]].enchant);
  1136. possision++;
  1137. }
  1138.  
  1139. var instanceInfoPossision = 31;
  1140. for (i = 0; i < raidInstancesSortOrder.length; i++)
  1141. {
  1142. for (var k = 0; k < raidDifficultySortOrder.length; k++)
  1143. {
  1144. var cellInfo = displayInfo.raid[raidInstancesSortOrder[i]][raidDifficultySortOrder[k]];
  1145. toonInfo.splice(instanceInfoPossision+i*8+k, 0, cellInfo.lockout + "/" + cellInfo.instanceLength);
  1146. }
  1147. for (k = 0; k < raidDifficultySortOrder.length; k++)
  1148. {
  1149. var secondCellInfo = displayInfo.raid[raidInstancesSortOrder[i]][raidDifficultySortOrder[k]];
  1150. toonInfo.splice(instanceInfoPossision+i*8+k+4, 0, secondCellInfo.progress + "/" + secondCellInfo.instanceLength + " [" + secondCellInfo.activeWeeks + "] (" + secondCellInfo.kills + ")");
  1151. }
  1152. }
  1153. return toonInfo;
  1154. }
  1155. function vercheck()
  1156. {
  1157. return current_version;
  1158. }
  1159.  
  1160. //When copy pasting, delete 0Looking at the bottom if it shows up, otherwise it'll cause an error
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement