🐭️ MouseHunt - Labyrinth HUD Enhancer

Enhances the Labyrinth HUD in a variety of ways.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        🐭️ MouseHunt - Labyrinth HUD Enhancer
// @version     1.1.0
// @description Enhances the Labyrinth HUD in a variety of ways.
// @license     MIT
// @author      brap
// @namespace   bradp
// @match       https://www.mousehuntgame.com/*
// @icon        https://i.mouse.rip/mouse.png
// @run-at      document-end
// @grant       none
// @require     https://cdn.jsdelivr.net/npm/[email protected]/mousehunt-utils.js
// @require     https://cdn.jsdelivr.net/npm/[email protected]

// ==/UserScript==
(function () {
  'use strict';
 
  const highlightDoors = () => {
    if ('intersection' !== user?.quests?.QuestLabyrinth?.status) {
      return;
    }
 
    const existingHighlight = document.querySelector('.mh-ui-labyrinth-highlight');
    if (existingHighlight) {
      existingHighlight.classList.remove('mh-ui-labyrinth-highlight');
    }
 
    const clues = user.quests.QuestLabyrinth.clues || [];
    const clue = clues.reduce((a, b) => a.quantity > b.quantity ? a : b);
 
    if (clue) {
      const doors = user.quests.QuestLabyrinth.doors || [];
      const matchingDoors = doors.filter((door) => {
        if (door.choice && door.choice.length) {
          return door.choice.includes(clue.type);
        }
        return false;
      });
      const bestDoor = matchingDoors.reduce((a, b) => a.choice.length > b.choice.length ? a : b);
 
      if (bestDoor) {
        const highlight = document.querySelector(`.labyrinthHUD-door.${bestDoor.css_class.replaceAll(' ', '.')}`);
        if (highlight) {
          highlight.classList.add('mh-ui-labyrinth-highlight');
        }
      }
    }
  };
 
  const main = () => {
    if ('labyrinth' !== getCurrentLocation()) {
      return;
    }
 
    // Always allow gems to be scrambled.
    scrambleGems();
    spinCompass();
 
    const appendTo = document.querySelector('.labyrinthHUD-hallwayDescription');
    if (!appendTo) {
      return;
    }
 
    const existing = document.querySelector('.mh-ui-labyrinth-step-counter');
    if (existing) {
      existing.remove();
    }
 
    const existingStepsToGo = document.querySelector('.mh-ui-labyrinth-steps-to-go');
    if (existingStepsToGo) {
      existingStepsToGo.remove();
    }
 
    const clueProgresses = document.querySelectorAll('.mh-ui-labyrinth-clue-count');
    if (clueProgresses) {
      clueProgresses.forEach((progress) => {
        progress.remove();
      });
    }
 
    // expand the clues bar with count
    const clueProgress = document.querySelectorAll('.labyrinthHUD-clue');
    if (clueProgress) {
      clueProgress.forEach((progress) => {
        const clueType = progress.classList.value.replace('labyrinthHUD-clue', '').replace('clueFound', '').trim();
 
        // check if user.quests.QuestLabyrinth.clues has a clue of this type
        const clues = user.quests.QuestLabyrinth.clues || [];
        const clue = clues.find((c) => c.type === clueType);
        if (clue) {
          progress.setAttribute('title', `${clue.quantity} found`);
          const text = makeElement('span', 'mh-ui-labyrinth-clue-count', `${clue.quantity}`);
          progress.appendChild(text);
        }
      });
    }
 
    if ('inactive' === user?.quests?.QuestLabyrinth?.lantern_status && user?.quests?.QuestLabyrinth?.hallway_tier >= 2) {
      const existingLanternReminder = document.querySelector('.mh-ui-labyrinth-lantern-reminder');
      if (existingLanternReminder) {
        existingLanternReminder.classList.remove('hidden');
      }
 
      const labyHud = document.querySelector('.labyrinthHUD-intersection');
      if (labyHud) {
        const lanternReminer = document.createElement('div');
        lanternReminer.classList.add('mh-ui-labyrinth-lantern-reminder');
        labyHud.appendChild(lanternReminer);
      }
    }
 
    if ('intersection' === user?.quests?.QuestLabyrinth?.status) {
      highlightDoors();
      return;
    }
 
    const hallwayLength = user.quests.QuestLabyrinth.hallway_length || 0;
    const tiles = user.quests.QuestLabyrinth.tiles || [];
    const completed = tiles.filter((tile) => tile.status.includes('complete'));
 
    makeElement('span', 'mh-ui-labyrinth-step-counter', `${completed.length}/${hallwayLength} steps completed.`, appendTo);
    const stepsToGo = hallwayLength - completed.length;
 
    if (stepsToGo !== 0) {
      const intersectionDoors = document.querySelector('.labyrinthHUD-doorContainer');
      if (intersectionDoors) {
        const tilesWithClues = tiles.filter((tile) => tile.status.includes('good'));
        // remove the string 'complete_good_' from each tile and sum the remaining numbers
        const cluesFound = tilesWithClues.reduce((a, b) => a + parseInt(b.status.replace('complete', '').replace('good_', '').trim()), 0);
        const cluesPerTile = (cluesFound / completed.length).toFixed(1).replace('.0', '');
 
        const existingIntersectionText = document.querySelector('.mh-ui-labyrinth-door-text');
        if (existingIntersectionText) {
          existingIntersectionText.remove();
        }
 
        const intersectionText = makeElement('div', 'mh-ui-labyrinth-door-text');
 
        makeElement('div', 'mh-ui-laby-steps', `${stepsToGo} hunt${(stepsToGo) > 1 ? 's' : ''} left in the hallway`, intersectionText);
        if (cluesPerTile !== 'NaN') {
          makeElement('div', 'mh-ui-laby-cpt', `Avg. ${cluesPerTile} clues per hunt`, intersectionText);
        }
 
        intersectionDoors.appendChild(intersectionText);
      }
    }
  };
 
  const scrambleGems = () => {
    const gems = document.querySelectorAll('.labyrinthHUD-scrambleGem');
    if (!gems) {
      return;
    }
 
    // remove the onclick attribute
    gems.forEach((gem) => {
      gem.removeAttribute('onclick');
      gem.addEventListener('click', () => {
        hg.views.HeadsUpDisplayLabyrinthView.labyrinthScrambleGem(gem, 2);
      });
    });
  };

  const spinCompass = () => {
    const container = document.querySelector('.labyrinthHUD');
    if (!container) {
      return;
    }

    const needle = document.createElement('div');
    needle.classList.add('mh-ui-labyrinth-compass-needle');
    container.appendChild(needle);
  };
  
  addStyles(`.mh-ui-labyrinth-step-counter {
    padding-right: 5px;
    margin-left: 5px;
    font-weight: 900;
    background-color: #000;
  }
  
  /* Make the clue counter bigger */
  .labyrinthHUD-clueBar-totalContainer {
    z-index: 10;
    width: auto;
    padding-left: 4px;
    font-size: 12px;
    border-radius: 6px;
  }
  
  .labyrinthHUD-clue {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    font-size: 10px;
  }
  
  .labyrinthHUD-clue-name {
    overflow: visible;
    text-overflow: unset;
  }
  
  .mh-ui-labyrinth-clue-count {
    padding: 4px;
    color: #050505;
    border-top-right-radius: 5px;
    border-bottom-right-radius: 5px;
  }
  
  .y .labyrinthHUD-clue-name,
  .y .mh-ui-labyrinth-clue-count {
    background-color: rgb(216 81 255 / 40%);
  }
  
  .h .labyrinthHUD-clue-name,
  .h .mh-ui-labyrinth-clue-count {
    background-color: rgb(33 226 255 / 40%);
  }
  
  .s .labyrinthHUD-clue-name,
  .s .mh-ui-labyrinth-clue-count {
    background-color: rgb(233 99 0 / 40%);
  }
  
  .t .labyrinthHUD-clue-name,
  .t .mh-ui-labyrinth-clue-count {
    background-color: rgb(255 228 0 / 40%);
  }
  
  .f .labyrinthHUD-clue-name,
  .f .mh-ui-labyrinth-clue-count {
    background-color: rgb(17 244 0 / 40%);
  }
  
  .m .labyrinthHUD-clue-name,
  .m .mh-ui-labyrinth-clue-count {
    color: #d3c5c5;
    background-color: rgb(106 106 106 / 40%);
  }
  
  /* Make the quantity counters bigger */
  .labyrinthHUD-item-quantity,
  .labyrinthHUD-scrambleDoors-quantity,
  .labyrinthHUD-scrambleClues-quantity,
  .labyrinthHUD-toggleLantern-quantity.quantity {
    position: absolute;
    top: 6px;
    padding: 0 5px;
    font-size: 11px;
    text-align: center;
    background-color: #000;
    border-radius: 5px;
  }
  
  .labyrinthHUD-item-quantity.quantity {
    top: 6px;
    left: 5px;
    display: block;
    width: 30px;
    margin: 0 !important;
  }
  
  .labyrinthHUD-scrambleDoors-quantity,
  .labyrinthHUD-scrambleClues-quantity,
  .labyrinthHUD-toggleLantern-quantity.quantity {
    display: inline-flex;
    align-items: center;
    width: auto;
    height: 18px;
    margin-right: 11px;
  }
  
  .labyrinthHUD-scrambleClues-quantity.quantity {
    left: -6px;
  }
  
  .labyrinthHUD-toggleLantern-quantity.quantity {
    right: -5px;
  }
  
  .labyrinthHUD-scrambleDoors-quantity.quantity {
    top: 0.5px;
    right: -7px;
    height: 9.5px;
    padding: 4px;
  }
  
  .labyrinthHUD-scrambleClues:hover .labyrinthHUD-scrambleClues-name,
  .labyrinthHUD-scrambleClues.disabled .labyrinthHUD-scrambleClues-name,
  .labyrinthHUD-scrambleClues:focus .labyrinthHUD-scrambleClues-name,
  .labyrinthHUD-scrambleClues-name {
    position: relative;
    color: transparent !important;
    text-shadow: none;
  }
  
  .labyrinthHUD-scrambleClues-name::after {
    position: absolute;
    top: 0;
    right: -30px;
    display: block;
    width: 50px;
    color: #eee;
    text-align: center;
    text-shadow: 0 0 1px #000;
    content: "Compass Magnet";
  }
  
  .labyrinthHUD-item:nth-child(1) .labyrinthHUD-item-name,
  .labyrinthHUD-item:nth-child(2) .labyrinthHUD-item-name,
  .labyrinthHUD-item:nth-child(3) .labyrinthHUD-item-name,
  .labyrinthHUD-item:nth-child(4) .labyrinthHUD-item-name,
  .labyrinthHUD-item:nth-child(5) .labyrinthHUD-item-name {
    width: 96px;
    margin-left: 47px;
    font-size: 11px;
    font-weight: 900;
    text-align: center;
    text-shadow: 0 0 1px #000;
    background: linear-gradient(180deg, rgb(112 112 112 / 0%) 0%, rgb(168 168 168 / 100%) 50%, rgb(112 112 112 / 0%) 100%);
    border-radius: 20px;
  }
  
  .labyrinthHUD-baitWarning {
    z-index: 6;
  }
  
  .labyrinthHUD-item:hover .labyrinthHUD-item-location,
  .labyrinthHUD-item:focus .labyrinthHUD-item-location {
    position: absolute;
    top: unset;
    bottom: -25px;
    padding: 3px;
    font-size: 9px;
    color: #000;
    text-align: center;
    background: #fff;
    border: 2px solid #000;
    border-radius: 10px;
    box-shadow: 2px 3px 4px #666;
  }
  
  /* hunts to go */
  .mh-ui-labyrinth-door-text {
    position: absolute;
    inset: 0;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    color: #fff;
    opacity: 0.8;
  }
  
  .mh-ui-laby-steps {
    margin-bottom: 3px;
    font-size: 13px;
  }
  
  .labyrinthHUD-doorContainer {
    position: relative;
  }
  
  /* hunts to go - door background */
  .labyrinthHUD-door.disabled.mystery {
    filter: brightness(0.4);
  }
  
  /* Highlight the best door */
  .labyrinthHUD-door.mh-ui-labyrinth-highlight {
    filter: brightness(1.3);
  }
  
  .labyrinthHUD-door.mh-ui-labyrinth-highlight::after {
    position: absolute;
    right: 5px;
    bottom: 5px;
    width: 30px;
    height: 30px;
    overflow: hidden;
    content: "";
    background: url(https://www.mousehuntgame.com/images/ui/events/winter_hunt_2013/checkmark.png?asset_cache_version=2) no-repeat 95% 90%;
  }
  
  .labyrinthHUD-confirm-padding .labyrinthHUD-door.mh-ui-labyrinth-highlight::after {
    background: none;
  }
  
  /* Popup summary */
  .labyrinthHUD-clueDrawer {
    padding-bottom: 11px;
    font-size: 11px;
  }
  
  .labyrinthHUD-clueDrawer-description {
    padding: 5px 0 10px;
    line-height: 17px;
    color: #fafafa;
    text-align: center;
  }
  
  .labyrinthHUD-clueDrawer-clue {
    margin: 10px 0;
  }
  
  .labyrinthHUD-clueDrawer-clue.tier-1 .labyrinthHUD-clueDrawer-exit.tier-1::after,
  .labyrinthHUD-clueDrawer-clue.tier-2 .labyrinthHUD-clueDrawer-exit.tier-2::after,
  .labyrinthHUD-clueDrawer-clue.tier-3 .labyrinthHUD-clueDrawer-exit.tier-3::after {
    background: none;
  }
  
  .labyrinthHUD-clueDrawer-exit {
    top: 0;
    bottom: 0;
    width: 1px;
    height: 10px;
    background: #8d8d8d;
    border-radius: 0;
  }
  
  .labyrinthHUD-clueDrawer-bar {
    height: 10px;
  }
  
  .labyrinthHUD-clueDrawer-barFrame {
    margin-right: 3px;
    border: 1px solid #585858;
    border-radius: 0;
  }
  
  .y .labyrinthHUD-clueDrawer-name,
  .y .labyrinthHUD-clueDrawer-quantity {
    border-bottom: 1px solid #d851ff;
  }
  
  .h .labyrinthHUD-clueDrawer-name,
  .h .labyrinthHUD-clueDrawer-quantity {
    border-bottom: 1px solid #21e2ff;
  }
  
  .s .labyrinthHUD-clueDrawer-name,
  .s .labyrinthHUD-clueDrawer-quantity {
    border-bottom: 1px solid #e96300;
  }
  
  .t .labyrinthHUD-clueDrawer-name,
  .t .labyrinthHUD-clueDrawer-quantity {
    border-bottom: 1px solid #ffe400;
  }
  
  .f .labyrinthHUD-clueDrawer-name,
  .f .labyrinthHUD-clueDrawer-quantity {
    border-bottom: 1px solid #11f400;
  }
  
  .labyrinthHUD-clueDrawer-name {
    padding-left: 3px;
    margin-right: -3px;
  }
  
  .labyrinthHUD-clueDrawer-quantity {
    padding-right: 3px;
    margin-left: -3px;
  }
  
  /* retreat button */
  .hudLocationContent a.labyrinthHUD-retreatButton {
    color: #707070 !important;
    background-color: rgb(0 0 0 / 50%);
  }
  
  .hudLocationContent a.labyrinthHUD-retreatButton:hover {
    color: #eee !important;
  }
  
  /* clue count on hover */
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete::after,
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.bad::after,
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_1::after,
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_2::after,
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_3::after,
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_4::after,
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_5::after,
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_6::after {
      position: absolute;
      top: 0;
      right: 0;
      left: 0;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      height: 100%;
      font-size: 15px;
      font-weight: 900;
      color: #000;
      text-align: center;
      text-shadow: 0 0 4px #c7ffad;
      content: "";
  }
  
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete::after {
      color: #0e0e0e;
      text-shadow: none;
      content: "0";
  }
  
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.bad::after {
      color: #c69898;
      text-shadow: none;
      content: "1";
  }
  
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_1::after {
      content: "1";
  }
  
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_2::after {
      content: "2";
  }
  
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_3::after {
      content: "3";
  }
  
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_4::after {
      content: "4";
  }
  
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_5::after {
      content: "5";
  }
  
  .labyrinthHUD-hallway-padding:hover .labyrinthHUD-hallway-tile.complete.good_6::after {
      content: "6";
  }

  .labyrinthHUD-scrambleGem:hover {
    background: url(https://www.mousehuntgame.com/images/ui/hud/labyrinth/animated_gem.gif?asset_cache_version=2) 0 0;
  }
  
  .mh-ui-labyrinth-lantern-reminder {
    position: absolute;
    bottom: 0;
    left: -8px;
    width: 75px;
    height: 75px;
    background: url(https://www.mousehuntgame.com/images/items/stats/transparent_thumb/d1c4774c7afebe379bef83d30b81f069.png?cv=2) 0 0 no-repeat;
    filter: drop-shadow(1px 0 8px #f6eac3);
    background-size: contain;
    transform-origin: bottom;
    animation: mh-ui-sway-side-to-side .75s;
    animation-iteration-count: 3;
  }

  .mh-ui-labyrinth-compass-needle {
    width: 28px;
    height: 30px;
    position: absolute;
    bottom: 36px;
    left: 141px;
    border-radius: 10px;
  }

  .mh-ui-labyrinth-compass-needle::after {
    position: absolute;
    content: "";
    background: url(https://i.mouse.rip/compass-needle.png) no-repeat;
    width: 10px;
    height: 20px;
    left: 9px;
    top: 5px;
  }

  .mh-ui-labyrinth-compass-needle:hover {
    animation: mh-ui-shake-compass-needle 1s infinite;
  }

  @keyframes mh-ui-shake-compass-needle {
    0% {
      transform: rotate(0deg);
    }

    25% {
      transform: rotate(-45deg);
    }

    75% {
      transform: rotate(45deg);
    }

    100% {
      transform: rotate(0deg);
    }
  }
  
  @keyframes mh-ui-sway-side-to-side {
    0% {
      transform: rotate(0deg);
    }
  
    25% {
      transform: rotate(-5deg);
    }
  
    75% {
      transform: rotate(5deg);
    }
  
    100% {
      transform: rotate(0deg);
    }
  }`)
 
  main();
 
  onAjaxRequest(main);
  onPageChange({ camp: { show: main } });
  onAjaxRequest(() => {
    setTimeout(main, 500);
  }, 'managers/ajax/turns/activeturn.php', true);

  migrateUserscript('🐭️ MouseHunt - Labyrinth HUD Enhancer', 'https://greasyfork.org/en/scripts/465603-mousehunt-labyrinth-hud-enhancer');
}());