🐭️ MouseHunt - Halloween Map Helper

Easily see and equip the cheese needed for Halloween Trick or Treat maps.

  1. // ==UserScript==
  2. // @name 🐭️ MouseHunt - Halloween Map Helper
  3. // @version 1.1.4
  4. // @description Easily see and equip the cheese needed for Halloween Trick or Treat maps.
  5. // @license MIT
  6. // @author bradp
  7. // @namespace bradp
  8. // @match https://www.mousehuntgame.com/*
  9. // @icon https://i.mouse.rip/mouse.png
  10. // @grant none
  11. // @run-at document-end
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. 'use strict';
  16.  
  17. const cheeseIdToId = {
  18. super_brie_cheese: 1114,
  19. cauldron_tier_1_cheese: 3305,
  20. cauldron_tier_2_cheese: 3306,
  21. cauldron_tier_3_cheese: 3307,
  22. cauldron_tier_4_cheese: 3308,
  23. };
  24.  
  25. const miceCheeses = [
  26. {
  27. name: 'Grey Recluse',
  28. cheese: 'Standard',
  29. cheeseId: 'super_brie_cheese'
  30. },
  31. {
  32. name: 'Cobweb',
  33. cheese: 'Standard',
  34. cheeseId: 'super_brie_cheese'
  35. },
  36. {
  37. name: 'Teenage Vampire',
  38. cheese: 'Standard',
  39. cheeseId: 'super_brie_cheese'
  40. },
  41. {
  42. name: 'Zombot Unipire',
  43. cheese: 'Standard',
  44. cheeseId: 'super_brie_cheese'
  45. },
  46. {
  47. name: 'Candy Cat',
  48. cheese: 'Standard',
  49. cheeseId: 'super_brie_cheese'
  50. },
  51. {
  52. name: 'Candy Goblin',
  53. cheese: 'Standard',
  54. cheeseId: 'super_brie_cheese'
  55. },
  56. {
  57. name: 'Shortcut',
  58. cheese: 'Standard',
  59. cheeseId: 'super_brie_cheese'
  60. },
  61. {
  62. name: 'Tricky Witch',
  63. cheese: 'Standard',
  64. cheeseId: 'super_brie_cheese'
  65. },
  66. {
  67. name: 'Sugar Rush',
  68. cheese: 'Standard',
  69. cheeseId: 'super_brie_cheese'
  70. },
  71. {
  72. name: 'Spirit Light',
  73. cheese: 'Monterey Jack-O-Lantern',
  74. cheeseId: 'cauldron_tier_1_cheese'
  75. },
  76. {
  77. name: 'Gourdborg',
  78. cheese: 'Monterey Jack-O-Lantern',
  79. cheeseId: 'cauldron_tier_1_cheese'
  80. },
  81. {
  82. name: 'Pumpkin Hoarder',
  83. cheese: 'Monterey Jack-O-Lantern',
  84. cheeseId: 'cauldron_tier_1_cheese'
  85. },
  86. {
  87. name: 'Trick',
  88. cheese: 'Monterey Jack-O-Lantern',
  89. cheeseId: 'cauldron_tier_1_cheese'
  90. },
  91. {
  92. name: 'Treat',
  93. cheese: 'Monterey Jack-O-Lantern',
  94. cheeseId: 'cauldron_tier_1_cheese'
  95. },
  96. {
  97. name: 'Wild Chainsaw',
  98. cheese: 'Monterey Jack-O-Lantern',
  99. cheeseId: 'cauldron_tier_1_cheese'
  100. },
  101. {
  102. name: 'Maize Harvester',
  103. cheese: 'Monterey Jack-O-Lantern',
  104. cheeseId: 'cauldron_tier_1_cheese'
  105. },
  106. {
  107. name: 'Creepy Marionette',
  108. cheese: 'Bonefort',
  109. cheeseId: 'cauldron_tier_2_cheese'
  110. },
  111. {
  112. name: 'Dire Lycan',
  113. cheese: 'Bonefort',
  114. cheeseId: 'cauldron_tier_2_cheese'
  115. },
  116. {
  117. name: 'Grave Robber',
  118. cheese: 'Bonefort',
  119. cheeseId: 'cauldron_tier_2_cheese'
  120. },
  121. {
  122. name: 'Hollowhead',
  123. cheese: 'Bonefort',
  124. cheeseId: 'cauldron_tier_2_cheese'
  125. },
  126. {
  127. name: 'Mousataur Priestess',
  128. cheese: 'Bonefort',
  129. cheeseId: 'cauldron_tier_2_cheese'
  130. },
  131. {
  132. name: 'Sandmouse',
  133. cheese: 'Bonefort',
  134. cheeseId: 'cauldron_tier_2_cheese'
  135. },
  136. {
  137. name: 'Titanic Brain-Taker',
  138. cheese: 'Bonefort',
  139. cheeseId: 'cauldron_tier_2_cheese'
  140. },
  141. {
  142. name: 'Tomb Exhumer',
  143. cheese: 'Bonefort',
  144. cheeseId: 'cauldron_tier_2_cheese'
  145. },
  146. {
  147. name: 'Admiral Arrrgh',
  148. cheese: 'Polter-Geitost',
  149. cheeseId: 'cauldron_tier_3_cheese'
  150. },
  151. {
  152. name: 'Captain Cannonball',
  153. cheese: 'Polter-Geitost',
  154. cheeseId: 'cauldron_tier_3_cheese'
  155. },
  156. {
  157. name: 'Ghost Pirate Queen',
  158. cheese: 'Polter-Geitost',
  159. cheeseId: 'cauldron_tier_3_cheese'
  160. },
  161. {
  162. name: 'Gourd Ghoul',
  163. cheese: 'Polter-Geitost',
  164. cheeseId: 'cauldron_tier_3_cheese'
  165. },
  166. {
  167. name: 'Scorned Pirate',
  168. cheese: 'Polter-Geitost',
  169. cheeseId: 'cauldron_tier_3_cheese'
  170. },
  171. {
  172. name: 'Spectral Butler',
  173. cheese: 'Polter-Geitost',
  174. cheeseId: 'cauldron_tier_3_cheese'
  175. },
  176. {
  177. name: 'Spectral Swashbuckler',
  178. cheese: 'Polter-Geitost',
  179. cheeseId: 'cauldron_tier_3_cheese'
  180. },
  181. {
  182. name: 'Baba Gaga',
  183. cheese: 'Scream',
  184. cheeseId: 'cauldron_tier_4_cheese'
  185. },
  186. {
  187. name: 'Bonbon Gummy Globlin',
  188. cheese: 'Scream',
  189. cheeseId: 'cauldron_tier_4_cheese'
  190. },
  191. {
  192. name: 'Hollowed',
  193. cheese: 'Scream',
  194. cheeseId: 'cauldron_tier_4_cheese'
  195. },
  196. {
  197. name: 'Hollowed Minion',
  198. cheese: 'Scream',
  199. cheeseId: 'cauldron_tier_4_cheese'
  200. },
  201. {
  202. name: 'Swamp Thang',
  203. cheese: 'Scream',
  204. cheeseId: 'cauldron_tier_4_cheese'
  205. }
  206. ];
  207.  
  208. /**
  209. * Add styles to the page.
  210. *
  211. * @param {string} styles The styles to add.
  212. */
  213. const addStyles = (styles) => {
  214. const existingStyles = document.getElementById('mh-mouseplace-custom-styles');
  215.  
  216. if (existingStyles) {
  217. existingStyles.innerHTML += styles;
  218. } else {
  219. const style = document.createElement('style');
  220. style.id = 'mh-mouseplace-custom-styles';
  221.  
  222. style.innerHTML = styles;
  223. document.head.appendChild(style);
  224. }
  225. };
  226.  
  227. /**
  228. * Do something when the overlay is shown or hidden.
  229. *
  230. * @param {Object} callbacks
  231. * @param {Function} callbacks.show The callback to call when the overlay is shown.
  232. * @param {Function} callbacks.hide The callback to call when the overlay is hidden.
  233. * @param {Function} callbacks.change The callback to call when the overlay is changed.
  234. */
  235. const onOverlayChange = (callbacks) => {
  236. const observer = new MutationObserver(() => {
  237. if (callbacks.change) {
  238. callbacks.change();
  239. }
  240.  
  241. if (document.getElementById('overlayBg').classList.length > 0) {
  242. if (callbacks.show) {
  243. callbacks.show();
  244. }
  245. } else if (callbacks.hide) {
  246. callbacks.hide();
  247. }
  248. });
  249. observer.observe(
  250. document.getElementById('overlayBg'),
  251. {
  252. attributes: true,
  253. attributeFilter: ['class']
  254. }
  255. );
  256. };
  257.  
  258. /**
  259. * Add links to the mouse details on the map.
  260. */
  261. const addCheeseLinks = () => {
  262. const overlayClasses = document.getElementById('overlayPopup').classList;
  263. if (! overlayClasses.contains('treasureMapPopup')) {
  264. return;
  265. }
  266.  
  267. const mapName = document.querySelector('.treasureMapView-mapMenu-rewardName');
  268. if (! mapName) {
  269. setTimeout(addCheeseLinks, 500);
  270. return;
  271. }
  272.  
  273. if (! mapName.innerText) {
  274. return;
  275. }
  276.  
  277. if (! mapName.innerText.includes('Halloween')) {
  278. return;
  279. }
  280.  
  281. const mouseIcon = document.querySelectorAll('.treasureMapView-goals-group-goal');
  282. if (mouseIcon.length === 0) {
  283. setTimeout(addCheeseLinks, 500);
  284. }
  285.  
  286. mouseIcon.forEach((mouse) => {
  287. const classes = mouse.classList;
  288. if (classes.contains('complete')) {
  289. return;
  290. }
  291.  
  292. const mouseName = mouse.querySelector('.treasureMapView-goals-group-goal-name span');
  293. if (! (mouseName && mouseName.textContent)) {
  294. return;
  295. }
  296.  
  297. const mouseContainer = mouse.querySelector('.treasureMapView-goals-group-goal-name');
  298. if (! mouseContainer) {
  299. return;
  300. }
  301.  
  302. // grab the data outof the micecheese array
  303. const mouseData = miceCheeses.find((mouseCheese) => mouseCheese.name === mouseName.textContent);
  304. if (! mouseData) {
  305. return;
  306. }
  307.  
  308. // add in a button and a background color
  309. const mouseButton = document.createElement('a');
  310. mouseButton.classList.add('mh-halloween-cheese-selector');
  311.  
  312. const currentCheese = user.bait_item_id; // eslint-disable-line no-undef
  313. if (cheeseIdToId[ mouseData.cheeseId ] === currentCheese) {
  314. mouseButton.textContent = `${mouseData.cheese} equipped`;
  315. } else {
  316. mouseButton.textContent = `Equip ${mouseData.cheese}`;
  317. }
  318.  
  319. const parent = mouseContainer.parentNode.parentNode;
  320. parent.classList.add('mh-halloween-cheese-' + mouseData.cheeseId);
  321.  
  322. parent.addEventListener('click', () => {
  323. hg.utils.TrapControl.setBait(mouseData.cheeseId); // eslint-disable-line no-undef
  324. hg.utils.TrapControl.go(); // eslint-disable-line no-undef
  325.  
  326. const close = document.getElementById('jsDialogClose');
  327. if (close) {
  328. close.click();
  329. }
  330. });
  331.  
  332. mouseContainer.appendChild(mouseButton);
  333. });
  334. };
  335.  
  336. addStyles(`.treasureMapView.event.halloween_treat_2021 .treasureMapView-goals-groups div:nth-child(2),
  337. .treasureMapView.event.halloween_trick_2021 .treasureMapView-goals-groups div:nth-child(2) {
  338. display: grid;
  339. grid-template-columns: repeat(2, 1fr);
  340. padding: 1em;
  341. }
  342.  
  343. .treasureMapView.event.halloween_treat_2021 .treasureMapView-highlight .treasureMapView-goals-groups div:nth-child(2),
  344. .treasureMapView.event.halloween_trick_2021 .treasureMapView-highlight .treasureMapView-goals-groups div:nth-child(2) {
  345. display: block;
  346. }
  347.  
  348. .treasureMapView.event.halloween_treat_2021 .treasureMapView-block-content .treasureMapView-goals-group-goal,
  349. .treasureMapView.event.halloween_trick_2021 .treasureMapView-block-content .treasureMapView-goals-group-goal {
  350. width: 90%;
  351. cursor: initial;
  352. }
  353.  
  354. .treasureMapView.event.halloween_treat_2021 .treasureMapView-goals-group-goal:hover:before,
  355. .treasureMapView.event.halloween_trick_2021 .treasureMapView-goals-group-goal:hover:before {
  356. background-color: transparent;
  357. left: 0;
  358. right: -2px;
  359. }
  360.  
  361. .treasureMapView.event.halloween_treat_2021 .treasureMapView-block-content .treasureMapView-goals-group-goal-padding .treasureMapView-goals-group-goal-name,
  362. .treasureMapView.event.halloween_trick_2021 .treasureMapView-block-content .treasureMapView-goals-group-goal-padding .treasureMapView-goals-group-goal-name {
  363. display: flex;
  364. flex-direction: column;
  365. }
  366.  
  367. .treasureMapView.event.halloween_treat_2021 .treasureMapView-goals-group-goal:hover:before,
  368. .treasureMapView.event.halloween_trick_2021 .treasureMapView-goals-group-goal:hover:before {
  369. box-shadow: 0 0 0 1px #646363;
  370. left: 0;
  371. right: 0;
  372. top: 0;
  373. bottom: 0;
  374. }
  375.  
  376. .mh-halloween-cheese-selector {
  377. margin-top: 0.5em;
  378. }
  379.  
  380. .mh-halloween-cheese-cauldron_tier_1_cheese {
  381. background-color: #ffaa4c !important;
  382. border-radius: 5px;
  383. }
  384.  
  385. .mh-halloween-cheese-cauldron_tier_2_cheese {
  386. background-color: #eac2d1 !important;
  387. border-radius: 5px;
  388. }
  389.  
  390. .mh-halloween-cheese-cauldron_tier_3_cheese {
  391. background-color: #cfeaec !important;
  392. border-radius: 5px;
  393. }
  394.  
  395. .mh-halloween-cheese-cauldron_tier_4_cheese {
  396. background-color: #b5d652 !important;
  397. border-radius: 5px;
  398. }`);
  399.  
  400. onOverlayChange({ show: addCheeseLinks });
  401. }());