MouseHunt - GWH Map Color Coder

Color codes mice on GWH maps according to decorations & cheese

  1. // ==UserScript==
  2. // @name MouseHunt - GWH Map Color Coder
  3. // @author Tran Situ (tsitu)
  4. // @namespace https://greasyfork.org/en/users/232363-tsitu
  5. // @version 1.3
  6. // @description Color codes mice on GWH maps according to decorations & cheese
  7. // @match http://www.mousehuntgame.com/*
  8. // @match https://www.mousehuntgame.com/*
  9. // ==/UserScript==
  10.  
  11. const sportMice = [
  12. "Sporty Ski Instructor",
  13. "Young Prodigy Racer",
  14. "Toboggan Technician",
  15. "Free Skiing",
  16. "Nitro Racer",
  17. "Rainbow Racer",
  18. "Double Black Diamond Racer",
  19. "Black Diamond Racer"
  20. ];
  21.  
  22. const toyMice = [
  23. "Nutcracker",
  24. "Toy",
  25. "Slay Ride",
  26. "Squeaker Claws",
  27. "Destructoy",
  28. "Toy Tinkerer",
  29. "Mad Elf",
  30. "Elf"
  31. ];
  32.  
  33. const ornamentalMice = [
  34. "Christmas Tree",
  35. "Stocking",
  36. "Candy Cane",
  37. "Ornament",
  38. "Missile Toe",
  39. "Wreath Thief",
  40. "Ribbon",
  41. "Snowglobe"
  42. ];
  43.  
  44. const snowMice = [
  45. "Snow Fort",
  46. "Snowball Hoarder",
  47. "S.N.O.W. Golem",
  48. "Snow Sorceress",
  49. "Reinbo",
  50. "Tundra Huntress",
  51. "Snowblower",
  52. "Snow Boulder"
  53. ];
  54.  
  55. const fireworksMice = [
  56. "Frightened Flying Fireworks",
  57. "New Year's",
  58. "Party Head"
  59. ];
  60.  
  61. const glazyMice = ["Glazy", "Joy"];
  62.  
  63. const pecanMice = [
  64. "Borean Commander",
  65. "Builder",
  66. "Frigid Foreman",
  67. "Glacia Ice Fist",
  68. "Great Winter Hunt Impostor",
  69. "Iceberg Sculptor",
  70. "Naughty Nougat",
  71. "Nice Knitting",
  72. "Ridiculous Sweater",
  73. "Shorts-All-Year",
  74. "Snow Golem Jockey",
  75. "Snow Scavenger",
  76. "Stuck Snowball"
  77. ];
  78.  
  79. const sbMice = [
  80. "Mouse of Winter Future",
  81. "Mouse of Winter Past",
  82. "Mouse of Winter Present",
  83. "Scrooge"
  84. ];
  85.  
  86. const standardMice = [
  87. "Confused Courier",
  88. "Gingerbread",
  89. "Greedy Al",
  90. "Hoarder",
  91. "Miser",
  92. "Present",
  93. "Triple Lutz"
  94. ];
  95.  
  96. const liscMice = ["Snow Golem Architect"];
  97.  
  98. const winterMice = ["Snowflake"];
  99.  
  100. function colorize() {
  101. let sportColor = "#c97c49"; // brown-ish
  102. let sportCount = 0;
  103. let toyColor = "#f06a60"; // red
  104. let toyCount = 0;
  105. let ornamentalColor = "#5ae031"; // green
  106. let ornamentalCount = 0;
  107. let snowColor = "#4fcaf0"; // blue
  108. let snowCount = 0;
  109. let fireworksColor = "#cd87ff"; // light purple
  110. let fireworksCount = 0;
  111. let glazyColor = "#ff9966"; // orange
  112. let glazyCount = 0;
  113. let pecanColor = "#ffff66"; // yellow
  114. let pecanCount = 0;
  115. let sbColor = "#66ffff"; // teal-ish
  116. let sbCount = 0;
  117. let standardColor = "#afa500"; // mountain dew-ish
  118. let standardCount = 0;
  119. let liscColor = "#6a62ad"; // medium purple
  120. let liscCount = 0;
  121. let winterColor = "#338838"; // darker green
  122. let winterCount = 0;
  123. const greyColor = "#949494";
  124.  
  125. const isChecked =
  126. localStorage.getItem("highlightPref") === "uncaught-only" ? true : false;
  127. const isCheckedStr = isChecked ? "checked" : "";
  128.  
  129. if (
  130. document.querySelectorAll(".treasureMapView-goals-group-goal").length === 0
  131. ) {
  132. return;
  133. }
  134.  
  135. document.querySelectorAll(".treasureMapView-goals-group-goal").forEach(el => {
  136. el.querySelector("span").style = "color: black; font-size: 11px;";
  137.  
  138. const mouseName = el.querySelector(".treasureMapView-goals-group-goal-name")
  139. .textContent;
  140.  
  141. if (sportMice.indexOf(mouseName) > -1) {
  142. el.style.backgroundColor = sportColor;
  143. if (el.className.indexOf(" complete ") < 0) {
  144. sportCount++;
  145. } else {
  146. if (isChecked) el.style.backgroundColor = "white";
  147. }
  148. } else if (toyMice.indexOf(mouseName) > -1) {
  149. el.style.backgroundColor = toyColor;
  150. if (el.className.indexOf(" complete ") < 0) {
  151. toyCount++;
  152. } else {
  153. if (isChecked) el.style.backgroundColor = "white";
  154. }
  155. } else if (ornamentalMice.indexOf(mouseName) > -1) {
  156. el.style.backgroundColor = ornamentalColor;
  157. if (el.className.indexOf(" complete ") < 0) {
  158. ornamentalCount++;
  159. } else {
  160. if (isChecked) el.style.backgroundColor = "white";
  161. }
  162. } else if (snowMice.indexOf(mouseName) > -1) {
  163. el.style.backgroundColor = snowColor;
  164. if (el.className.indexOf(" complete ") < 0) {
  165. snowCount++;
  166. } else {
  167. if (isChecked) el.style.backgroundColor = "white";
  168. }
  169. } else if (fireworksMice.indexOf(mouseName) > -1) {
  170. el.style.backgroundColor = fireworksColor;
  171. if (el.className.indexOf(" complete ") < 0) {
  172. fireworksCount++;
  173. } else {
  174. if (isChecked) el.style.backgroundColor = "white";
  175. }
  176. } else if (glazyMice.indexOf(mouseName) > -1) {
  177. el.style.backgroundColor = glazyColor;
  178. if (el.className.indexOf(" complete ") < 0) {
  179. glazyCount++;
  180. } else {
  181. if (isChecked) el.style.backgroundColor = "white";
  182. }
  183. } else if (pecanMice.indexOf(mouseName) > -1) {
  184. el.style.backgroundColor = pecanColor;
  185. if (el.className.indexOf(" complete ") < 0) {
  186. pecanCount++;
  187. } else {
  188. if (isChecked) el.style.backgroundColor = "white";
  189. }
  190. } else if (sbMice.indexOf(mouseName) > -1) {
  191. el.style.backgroundColor = sbColor;
  192. if (el.className.indexOf(" complete ") < 0) {
  193. sbCount++;
  194. } else {
  195. if (isChecked) el.style.backgroundColor = "white";
  196. }
  197. } else if (standardMice.indexOf(mouseName) > -1) {
  198. el.style.backgroundColor = standardColor;
  199. if (el.className.indexOf(" complete ") < 0) {
  200. standardCount++;
  201. } else {
  202. if (isChecked) el.style.backgroundColor = "white";
  203. }
  204. } else if (liscMice.indexOf(mouseName) > -1) {
  205. el.style.backgroundColor = liscColor;
  206. if (el.className.indexOf(" complete ") < 0) {
  207. liscCount++;
  208. } else {
  209. if (isChecked) el.style.backgroundColor = "white";
  210. }
  211. } else if (winterMice.indexOf(mouseName) > -1) {
  212. el.style.backgroundColor = winterColor;
  213. if (el.className.indexOf(" complete ") < 0) {
  214. winterCount++;
  215. } else {
  216. if (isChecked) el.style.backgroundColor = "white";
  217. }
  218. }
  219. });
  220.  
  221. sportColor = sportCount > 0 ? sportColor : greyColor;
  222. toyColor = toyCount > 0 ? toyColor : greyColor;
  223. ornamentalColor = ornamentalCount > 0 ? ornamentalColor : greyColor;
  224. snowColor = snowCount > 0 ? snowColor : greyColor;
  225. fireworksColor = fireworksCount > 0 ? fireworksColor : greyColor;
  226. glazyColor = glazyCount > 0 ? glazyColor : greyColor;
  227. pecanColor = pecanCount > 0 ? pecanColor : greyColor;
  228. sbColor = sbCount > 0 ? sbColor : greyColor;
  229. standardColor = standardCount > 0 ? standardColor : greyColor;
  230. liscColor = liscCount > 0 ? liscColor : greyColor;
  231. winterColor = winterCount > 0 ? winterColor : greyColor;
  232.  
  233. // Remove existing GWH Map related elements before proceeding
  234. document.querySelectorAll(".tsitu-gwh-map").forEach(el => el.remove());
  235.  
  236. const masterDiv = document.createElement("div");
  237. masterDiv.className = "tsitu-gwh-map";
  238. masterDiv.style =
  239. "display: inline-flex; margin-bottom: 10px; width: 100%; text-align: center; line-height: 1.5; overflow: hidden";
  240. const spanStyle =
  241. "; width: auto; padding: 5px; font-weight: bold; font-size: 12.75px; text-shadow: 0px 0px 11px white";
  242.  
  243. const sportSpan = document.createElement("span");
  244. sportSpan.style = "background-color: " + sportColor + spanStyle;
  245. sportSpan.innerHTML = "Sport<br>" + sportCount;
  246.  
  247. const toySpan = document.createElement("span");
  248. toySpan.style = "background-color: " + toyColor + spanStyle;
  249. toySpan.innerHTML = "Toy<br>" + toyCount;
  250.  
  251. const ornamentalSpan = document.createElement("span");
  252. ornamentalSpan.style = "background-color: " + ornamentalColor + spanStyle;
  253. ornamentalSpan.innerHTML = "Orna<br>" + ornamentalCount;
  254.  
  255. const snowSpan = document.createElement("span");
  256. snowSpan.style = "background-color: " + snowColor + spanStyle;
  257. snowSpan.innerHTML = "Snow<br>" + snowCount;
  258.  
  259. const fireworksSpan = document.createElement("span");
  260. fireworksSpan.style = "background-color: " + fireworksColor + spanStyle;
  261. fireworksSpan.innerHTML = "Fire<br>" + fireworksCount;
  262.  
  263. const glazySpan = document.createElement("span");
  264. glazySpan.style = "background-color: " + glazyColor + spanStyle;
  265. glazySpan.innerHTML = "Glazy<br>" + glazyCount;
  266.  
  267. const pecanSpan = document.createElement("span");
  268. pecanSpan.style = "background-color: " + pecanColor + spanStyle;
  269. pecanSpan.innerHTML = "Pecan<br>" + pecanCount;
  270.  
  271. const sbSpan = document.createElement("span");
  272. sbSpan.style = "background-color: " + sbColor + spanStyle;
  273. sbSpan.innerHTML = "SB+<br>" + sbCount;
  274.  
  275. const standardSpan = document.createElement("span");
  276. standardSpan.style = "background-color: " + standardColor + spanStyle;
  277. standardSpan.innerHTML = "Basic<br>" + standardCount;
  278.  
  279. const liscSpan = document.createElement("span");
  280. liscSpan.style = "background-color: " + liscColor + spanStyle;
  281. liscSpan.innerHTML = "LISC<br>" + liscCount;
  282.  
  283. const winterSpan = document.createElement("span");
  284. winterSpan.style = "background-color: " + winterColor + spanStyle;
  285. winterSpan.innerHTML = "Winter<br>" + winterCount;
  286.  
  287. // Highlight uncaught only feature
  288. const highlightLabel = document.createElement("label");
  289. highlightLabel.htmlFor = "tsitu-highlight-box";
  290. highlightLabel.innerText = "Highlight uncaught mice only";
  291.  
  292. const highlightBox = document.createElement("input");
  293. highlightBox.type = "checkbox";
  294. highlightBox.name = "tsitu-highlight-box";
  295. highlightBox.style.verticalAlign = "middle";
  296. highlightBox.checked = isChecked;
  297. highlightBox.addEventListener("click", function () {
  298. if (highlightBox.checked) {
  299. localStorage.setItem("highlightPref", "uncaught-only");
  300. } else {
  301. localStorage.setItem("highlightPref", "all");
  302. }
  303. colorize();
  304. });
  305.  
  306. const highlightDiv = document.createElement("div");
  307. highlightDiv.className = "tsitu-gwh-map";
  308. highlightDiv.style = "float: right; position: relative; z-index: 1";
  309. highlightDiv.appendChild(highlightBox);
  310. highlightDiv.appendChild(highlightLabel);
  311.  
  312. // Assemble masterDiv
  313. masterDiv.appendChild(sportSpan);
  314. masterDiv.appendChild(toySpan);
  315. masterDiv.appendChild(ornamentalSpan);
  316. masterDiv.appendChild(snowSpan);
  317. masterDiv.appendChild(fireworksSpan);
  318. masterDiv.appendChild(glazySpan);
  319. masterDiv.appendChild(pecanSpan);
  320. masterDiv.appendChild(sbSpan);
  321. masterDiv.appendChild(standardSpan);
  322. masterDiv.appendChild(liscSpan);
  323. masterDiv.appendChild(winterSpan);
  324.  
  325. // Inject into DOM
  326. const insertEl = document.querySelector(
  327. ".treasureMapView-leftBlock .treasureMapView-block-content"
  328. );
  329. if (
  330. insertEl &&
  331. document.querySelector(
  332. ".treasureMapRootView-header-navigation-item.tasks.active" // On "Active Maps"
  333. )
  334. ) {
  335. insertEl.insertAdjacentElement("afterbegin", highlightDiv);
  336. insertEl.insertAdjacentElement("afterbegin", masterDiv);
  337. }
  338.  
  339. // "Goals" button
  340. document.querySelector("[data-type='show_goals']").onclick = function () {
  341. colorize();
  342. };
  343. }
  344.  
  345. // Listen to XHRs, opening a map always at least triggers board.php
  346. const originalOpen = XMLHttpRequest.prototype.open;
  347. XMLHttpRequest.prototype.open = function () {
  348. this.addEventListener("load", function () {
  349. const chestEl = document.querySelector(
  350. ".treasureMapView-mapMenu-rewardName"
  351. );
  352.  
  353. // 2019: Nice/Naughty List descriptors present in HUD, not so in 2020
  354. // 2020: "2018-2020 [Rare] Nice Treasure Chest" & "2020 [Rare] Naughty Treasure Chest"
  355. if (chestEl) {
  356. const chestName = chestEl.textContent;
  357. if (
  358. chestName &&
  359. (chestName.indexOf("Nice Treasure Chest") >= 0 ||
  360. chestName.indexOf("Naughty Treasure Chest") >= 0)
  361. ) {
  362. colorize();
  363. }
  364. }
  365. });
  366. originalOpen.apply(this, arguments);
  367. };