MouseHunt - SP / FI Map Color Coder 2021

Color codes mice on SP / FI maps according to decorations // & cheese. Based off tsitu's work.

  1. // ==UserScript==
  2. // @name MouseHunt - SP / FI Map Color Coder 2021
  3. // @author Tran Situ (tsitu) & Leppy
  4. // @version 1.3.3
  5. // @description Color codes mice on SP / FI maps according to decorations // & cheese. Based off tsitu's work.
  6. // @match http://www.mousehuntgame.com/*
  7. // @match https://www.mousehuntgame.com/*
  8. // @include http://apps.facebook.com/mousehunt/*
  9. // @include https://apps.facebook.com/mousehunt/*
  10. // @grant GM_setClipboard
  11. // Most of the work comes from in59te's original sky pirate map color coder.
  12. // Thanks Warden Slayer for adding in the support to copy 'sniper list' into the clipboard.
  13. // Only added annotation for type of mice that are missing, as well as SP mice
  14. // - For Guard, A for Appraiser, T for Tinkerer, G for Geologist, E for Empress
  15. // - SP means SP protector
  16. // - Par means paragon
  17. // - HAI means HAI friend
  18. // - * at LP means the SB+ mouse, i.e. CM
  19. // @namespace https://gf.qytechs.cn/users/967077
  20. // ==/UserScript==
  21. const launchPadMice = [
  22. "Skydiver",
  23. "Sky Greaser",
  24. "Launchpad Labourer",
  25. "Cloud Miner",
  26. ];
  27.  
  28. const arcaneMice = [
  29. "Sky Glass Sorcerer",
  30. "Sky Glass Glazier",
  31. "Sky Dancer",
  32. "Sky Highborne",
  33. "Paragon of Arcane",
  34. "Sky Glider",
  35. ];
  36.  
  37. const forgottenMice = [
  38. "Spry Sky Explorer",
  39. "Spry Sky Seer",
  40. "Cumulost",
  41. "Spheric Diviner",
  42. "Paragon of Forgotten",
  43. "Forgotten Elder",
  44. ];
  45.  
  46. const hydroMice = [
  47. "Nimbomancer",
  48. "Sky Surfer",
  49. "Cute Cloud Conjurer",
  50. "Mist Maker",
  51. "Paragon of Water",
  52. "Cloud Strider",
  53. ];
  54.  
  55. const shadowMice = [
  56. "Astrological Astronomer",
  57. "Overcaster",
  58. "Stratocaster",
  59. "Shadow Sage",
  60. "Paragon of Shadow",
  61. "Zealous Academic",
  62. ];
  63.  
  64. const physicalMice = [
  65. "Ground Gavaleer",
  66. "Sky Swordsman",
  67. "Herc",
  68. "Sky Squire",
  69. "Paragon of Strength",
  70. "Glamorous Gladiator",
  71. ];
  72.  
  73. const draconicMice = [
  74. "Tiny Dragonfly",
  75. "Lancer Guard",
  76. "Dragonbreather",
  77. "Regal Spearman",
  78. "Paragon of Dragons",
  79. "Empyrean Javelineer",
  80. ];
  81.  
  82. const lawMice = [
  83. "Devious Gentleman",
  84. "Stack of Thieves",
  85. "Lawbender",
  86. "Agent M",
  87. "Paragon of the Lawless",
  88. "Aristo-Cat Burglar",
  89. ];
  90.  
  91. const tacticalMice = [
  92. "Worried Wayfinder",
  93. "Gyrologer",
  94. "Seasoned Islandographer",
  95. "Captain Cloudkicker",
  96. "Paragon of Tactics",
  97. "Rocketeer",
  98. ];
  99.  
  100. const pirateMice = [
  101. "Suave Pirate",
  102. "Cutthroat Pirate",
  103. "Cutthroat Cannoneer",
  104. "Scarlet Revenger",
  105. "Mairitime Pirate",
  106. "Admiral Cloudbeard",
  107. "Peggy the Plunderer",
  108. ];
  109.  
  110. const guardMice = [
  111. "Empyrean Appraiser",
  112. "Consumed Charm Tinkerer",
  113. "Empyrean Geologist",
  114. "Empyrean Empress",
  115. ];
  116.  
  117. const richMice = ["Richard the Rich", "Fortuitous Fool"];
  118.  
  119. const wardenMice = [
  120. "Warden of Rain",
  121. "Warden of Fog",
  122. "Warden of Frost",
  123. "Warden of Wind",
  124. ];
  125.  
  126. const spMaps = [
  127. "Sky Pirate Treasure Chest",
  128. "Rare Sky Pirate Treasure Chest",
  129. "Empyrean Sky Palace Treasure Chest",
  130. "Rare Empyrean Sky Palace Treasure Chest",
  131. ];
  132.  
  133. function sniperListForSinglePowerType(
  134. emoji,
  135. powerType,
  136. paragonAlias,
  137. SPAlias,
  138. SPName,
  139. count,
  140. bossCount,
  141. SPCount
  142. ) {
  143. let output = "";
  144. // Nothing to display if there is no mice with this power type.
  145. if (count > 0) {
  146. output = output + emoji + powerType;
  147. const fields = [];
  148. if (bossCount > 0) {
  149. let pnf = "";
  150. /*if (count - bossCount - SPCount > 0) {
  151. pnf = "Paragon & Friends "
  152. } else {
  153. pnf = "Paragon only "
  154. }*/
  155.  
  156. if (paragonAlias != "") {
  157. pnf = pnf + "(" + paragonAlias + ") ";
  158. }
  159. fields.push(pnf + "$$$");
  160. } else {
  161. fields.push("---");
  162. }
  163. /*if (SPCount > 0) {
  164. fields.push("SP " + SPName + " $$")*/
  165.  
  166. if (SPCount > 0) {
  167. //fields.push(SPAlias + " $$")
  168. fields.push(SPName + " $$");
  169. } else {
  170. fields.push(" --");
  171. }
  172. output = output + fields.join(" | ");
  173. }
  174. return output;
  175. }
  176.  
  177. function sniperListForMisc(
  178. pirateT1Count,
  179. pirateT2Count,
  180. pirateSPCount,
  181. richCount,
  182. richSPCount,
  183. guardAppraiserCount,
  184. guardTinkererCount,
  185. guardGeologistCount,
  186. guardEmpressCount
  187. ) {
  188. const entries = [];
  189. if (pirateSPCount > 0) {
  190. entries.push("Peggy $$");
  191. } else {
  192. if (pirateT2Count > 0) {
  193. entries.push("Pirate tier 2 $$");
  194. }
  195. if (pirateT1Count > 0) {
  196. entries.push("Pirate tier 1 $$");
  197. }
  198. }
  199. if (richCount - richSPCount > 0) {
  200. entries.push("Richard $$");
  201. }
  202. if (richSPCount > 0) {
  203. entries.push("Fool $$");
  204. }
  205. if (guardAppraiserCount > 0) {
  206. entries.push("Appraiser $$");
  207. }
  208. if (guardTinkererCount > 0) {
  209. entries.push("Tinkerer $$");
  210. }
  211. if (guardGeologistCount > 0) {
  212. entries.push("Geologist $$");
  213. }
  214. if (guardEmpressCount > 0) {
  215. entries.push("Empress $$");
  216. }
  217.  
  218. let output = "";
  219. if (entries.length > 0) {
  220. output = output + entries.join(" | ");
  221. }
  222.  
  223. return output;
  224. }
  225.  
  226. function sniperListForWardens(
  227. wardenRainCount,
  228. wardenFogCount,
  229. wardenFrostCount,
  230. wardenWindCount
  231. ) {
  232. const wardens = [];
  233. if (wardenRainCount > 0) {
  234. wardens.push("Rain");
  235. }
  236. if (wardenFogCount > 0) {
  237. wardens.push("Fog");
  238. }
  239. if (wardenFrostCount > 0) {
  240. wardens.push("Frost");
  241. }
  242. if (wardenWindCount > 0) {
  243. wardens.push("Wind");
  244. }
  245.  
  246. let output = "";
  247. if (wardens.length > 0) {
  248. output = output + "Warden " + wardens.join(" | ") + " $$ ea";
  249. }
  250.  
  251. return output;
  252. }
  253.  
  254. function sniperList(
  255. arcaneCount,
  256. arcaneHAICount,
  257. arcaneBossCount,
  258. arcaneSPCount,
  259. forgottenCount,
  260. forgottenHAICount,
  261. forgottenBossCount,
  262. forgottenSPCount,
  263. hydroCount,
  264. hydroHAICount,
  265. hydroBossCount,
  266. hydroSPCount,
  267. shadowCount,
  268. shadowHAICount,
  269. shadowBossCount,
  270. shadowSPCount,
  271. draconicCount,
  272. draconicHAICount,
  273. draconicBossCount,
  274. draconicSPCount,
  275. lawCount,
  276. lawHAICount,
  277. lawBossCount,
  278. lawSPCount,
  279. physicalCount,
  280. physicalHAICount,
  281. physicalBossCount,
  282. physicalSPCount,
  283. tacticalCount,
  284. tacticalHAICount,
  285. tacticalBossCount,
  286. tacticalSPCount,
  287. pirateT1Count,
  288. pirateT2Count,
  289. pirateSPCount,
  290. richCount,
  291. richSPCount,
  292. guardAppraiserCount,
  293. guardTinkererCount,
  294. guardGeologistCount,
  295. guardEmpressCount,
  296. wardenRainCount,
  297. wardenFogCount,
  298. wardenFrostCount,
  299. wardenWindCount,
  300. powerSPCount,
  301. powerBossCount
  302. ) {
  303. const argsArray = [
  304. [
  305. ":arcane:",
  306. "Arcane",
  307. "",
  308. "Glider",
  309. arcaneMice[5],
  310. arcaneCount,
  311. arcaneBossCount,
  312. arcaneSPCount,
  313. ],
  314. [
  315. ":forgotten:",
  316. "Forgotten",
  317. "",
  318. "Elder",
  319. forgottenMice[5],
  320. forgottenCount,
  321. forgottenBossCount,
  322. forgottenSPCount,
  323. ],
  324. [
  325. ":hydro:",
  326. "Hydro",
  327. "Water",
  328. "Strider",
  329. hydroMice[5],
  330. hydroCount,
  331. hydroBossCount,
  332. hydroSPCount,
  333. ],
  334. [
  335. ":shadow:",
  336. "Shadow",
  337. "",
  338. "Zealous",
  339. shadowMice[5],
  340. shadowCount,
  341. shadowBossCount,
  342. shadowSPCount,
  343. ],
  344. [
  345. ":draconic:",
  346. "Draconic",
  347. "Dragons",
  348. "Javelineer",
  349. draconicMice[5],
  350. draconicCount,
  351. draconicBossCount,
  352. draconicSPCount,
  353. ],
  354. [
  355. ":law:",
  356. "Law",
  357. "Lawless",
  358. "Aristocat",
  359. lawMice[5],
  360. lawCount,
  361. lawBossCount,
  362. lawSPCount,
  363. ],
  364. [
  365. ":physical:",
  366. "Physical",
  367. "Strength",
  368. "Gladiator",
  369. physicalMice[5],
  370. physicalCount,
  371. physicalBossCount,
  372. physicalSPCount,
  373. ],
  374. [
  375. ":tactical:",
  376. "Tactical",
  377. "",
  378. "Rocketeer",
  379. tacticalMice[5],
  380. tacticalCount,
  381. tacticalBossCount,
  382. tacticalSPCount,
  383. ],
  384. ];
  385. let textArray = ["LF Snipers P&F | SP"];
  386. argsArray.forEach(function (arrayItem, index) {
  387. const thisText = sniperListForSinglePowerType(
  388. arrayItem[0],
  389. arrayItem[1],
  390. arrayItem[2],
  391. arrayItem[3],
  392. arrayItem[4],
  393. arrayItem[5],
  394. arrayItem[6],
  395. arrayItem[7]
  396. );
  397. if (thisText) {
  398. textArray.push(thisText);
  399. }
  400. });
  401. textArray.push(
  402. sniperListForMisc(
  403. pirateT1Count,
  404. pirateT2Count,
  405. pirateSPCount,
  406. richCount,
  407. richSPCount,
  408. guardAppraiserCount,
  409. guardTinkererCount,
  410. guardGeologistCount,
  411. guardEmpressCount
  412. )
  413. );
  414. if (textArray.length < 10) {
  415. textArray.push(
  416. sniperListForWardens(
  417. wardenRainCount,
  418. wardenFogCount,
  419. wardenFrostCount,
  420. wardenWindCount
  421. )
  422. );
  423. }
  424. const finalTable = textArray.join("\n");
  425. return finalTable;
  426. }
  427.  
  428. function createSpan(
  429. color,
  430. spanStyle,
  431. label,
  432. count,
  433. SPCount,
  434. bossCount,
  435. HAICount,
  436. allSPCount,
  437. powerBossCount,
  438. powerHAICount
  439. ) {
  440. const span = document.createElement("span");
  441. span.style = "background-color: " + color + spanStyle;
  442. span.innerHTML = label + "<br>" + count;
  443. let spanExtra = "";
  444. if (allSPCount > 0) {
  445. spanExtra = spanExtra + "<br>";
  446. if (SPCount > 0) {
  447. spanExtra = spanExtra + "SP";
  448. }
  449. }
  450. if (powerBossCount > 0) {
  451. spanExtra = spanExtra + "<br>";
  452. if (bossCount > 0) {
  453. spanExtra = spanExtra + "Par";
  454. }
  455. }
  456. if (powerHAICount > 0) {
  457. spanExtra = spanExtra + "<br>";
  458. if (HAICount > 0) {
  459. spanExtra = spanExtra + "HAI";
  460. }
  461. }
  462. if (spanExtra != "") {
  463. span.innerHTML = span.innerHTML + spanExtra;
  464. }
  465. return span;
  466. }
  467.  
  468. function colorize(copyFlag) {
  469. let launchPadColor = "#c97c49"; // brown
  470. let launchPadCount = 0;
  471. let launchPadSBCount = 0;
  472. let arcaneColor = "#0be496"; // light green
  473. let arcaneCount = 0;
  474. let arcaneHAICount = 0;
  475. let arcaneBossCount = 0;
  476. let arcaneSPCount = 0;
  477. let forgottenColor = "#338838"; // darker green
  478. let forgottenCount = 0;
  479. let forgottenHAICount = 0;
  480. let forgottenBossCount = 0;
  481. let forgottenSPCount = 0;
  482. let hydroColor = "#5d9fce"; // blue
  483. let hydroCount = 0;
  484. let hydroHAICount = 0;
  485. let hydroBossCount = 0;
  486. let hydroSPCount = 0;
  487. let shadowColor = "#8f75e2"; // purple
  488. let shadowCount = 0;
  489. let shadowHAICount = 0;
  490. let shadowBossCount = 0;
  491. let shadowSPCount = 0;
  492. let draconicColor = "#f06a60"; // red
  493. let draconicCount = 0;
  494. let draconicHAICount = 0;
  495. let draconicBossCount = 0;
  496. let draconicSPCount = 0;
  497. let lawColor = "#f9a645"; // orange
  498. let lawCount = 0;
  499. let lawHAICount = 0;
  500. let lawBossCount = 0;
  501. let lawSPCount = 0;
  502. let physicalColor = "#5ae031"; // green;
  503. let physicalCount = 0;
  504. let physicalHAICount = 0;
  505. let physicalBossCount = 0;
  506. let physicalSPCount = 0;
  507. let tacticalColor = "#fff935"; // yellow
  508. let tacticalCount = 0;
  509. let tacticalHAICount = 0;
  510. let tacticalBossCount = 0;
  511. let tacticalSPCount = 0;
  512. let pirateColor = "#ECA4A6"; // pink
  513. let pirateCount = 0;
  514. let pirateT1Count = 0;
  515. let pirateT2Count = 0;
  516. let pirateSPCount = 0;
  517. let richColor = "#FFD700"; // gold
  518. let richCount = 0;
  519. let richSPCount = 0;
  520. let wardenColor = "ffffff"; // white
  521. let wardenCount = 0;
  522. let wardenRainCount = 0;
  523. let wardenFogCount = 0;
  524. let wardenFrostCount = 0;
  525. let wardenWindCount = 0;
  526. let guardColor = "#85C1E9"; // light blue
  527. let guardCount = 0;
  528. let guardAppraiserCount = 0;
  529. let guardTinkererCount = 0;
  530. let guardGeologistCount = 0;
  531. let guardEmpressCount = 0;
  532.  
  533. let powerHAICount = 0;
  534. let powerBossCount = 0;
  535. let powerSPCount = 0;
  536. let allSPCount = 0;
  537. const greyColor = "#949494";
  538.  
  539. const isChecked =
  540. localStorage.getItem("highlightPref") === "uncaught-only" ? true : false;
  541. const isCheckedStr = isChecked ? "checked" : "";
  542.  
  543. if (
  544. document.querySelectorAll(".treasureMapView-goals-group-goal").length === 0
  545. ) {
  546. return;
  547. }
  548.  
  549. document
  550. .querySelectorAll(".treasureMapView-goals-group-goal")
  551. .forEach((el) => {
  552. el.querySelector("span").style = "color: black; font-size: 11px;";
  553.  
  554. const mouseName = el.querySelector(
  555. ".treasureMapView-goals-group-goal-name"
  556. ).textContent;
  557.  
  558. if (guardMice.indexOf(mouseName) > -1) {
  559. el.style.backgroundColor = guardColor;
  560. if (el.className.indexOf(" complete ") < 0) {
  561. guardCount++;
  562. if (guardMice.indexOf(mouseName) == 0) {
  563. guardAppraiserCount++;
  564. } else if (guardMice.indexOf(mouseName) == 1) {
  565. guardTinkererCount++;
  566. } else if (guardMice.indexOf(mouseName) == 2) {
  567. guardGeologistCount++;
  568. } else if (guardMice.indexOf(mouseName) == 3) {
  569. guardEmpressCount++;
  570. }
  571. } else {
  572. if (isChecked) el.style.backgroundColor = "white";
  573. }
  574. } else if (arcaneMice.indexOf(mouseName) > -1) {
  575. el.style.backgroundColor = arcaneColor;
  576. if (el.className.indexOf(" complete ") < 0) {
  577. arcaneCount++;
  578. if (arcaneMice.indexOf(mouseName) == 3) {
  579. arcaneHAICount++;
  580. } else if (arcaneMice.indexOf(mouseName) == 4) {
  581. arcaneBossCount++;
  582. } else if (arcaneMice.indexOf(mouseName) == 5) {
  583. arcaneSPCount++;
  584. }
  585. } else {
  586. if (isChecked) el.style.backgroundColor = "white";
  587. }
  588. } else if (forgottenMice.indexOf(mouseName) > -1) {
  589. el.style.backgroundColor = forgottenColor;
  590. if (el.className.indexOf(" complete ") < 0) {
  591. forgottenCount++;
  592. if (forgottenMice.indexOf(mouseName) == 3) {
  593. forgottenHAICount++;
  594. } else if (forgottenMice.indexOf(mouseName) == 4) {
  595. forgottenBossCount++;
  596. } else if (forgottenMice.indexOf(mouseName) == 5) {
  597. forgottenSPCount++;
  598. }
  599. } else {
  600. if (isChecked) el.style.backgroundColor = "white";
  601. }
  602. } else if (hydroMice.indexOf(mouseName) > -1) {
  603. el.style.backgroundColor = hydroColor;
  604. if (el.className.indexOf(" complete ") < 0) {
  605. hydroCount++;
  606. if (hydroMice.indexOf(mouseName) == 3) {
  607. hydroHAICount++;
  608. } else if (hydroMice.indexOf(mouseName) == 4) {
  609. hydroBossCount++;
  610. } else if (hydroMice.indexOf(mouseName) == 5) {
  611. hydroSPCount++;
  612. }
  613. } else {
  614. if (isChecked) el.style.backgroundColor = "white";
  615. }
  616. } else if (shadowMice.indexOf(mouseName) > -1) {
  617. el.style.backgroundColor = shadowColor;
  618. if (el.className.indexOf(" complete ") < 0) {
  619. shadowCount++;
  620. if (shadowMice.indexOf(mouseName) == 3) {
  621. shadowHAICount++;
  622. } else if (shadowMice.indexOf(mouseName) == 4) {
  623. shadowBossCount++;
  624. } else if (shadowMice.indexOf(mouseName) == 5) {
  625. shadowSPCount++;
  626. }
  627. } else {
  628. if (isChecked) el.style.backgroundColor = "white";
  629. }
  630. } else if (draconicMice.indexOf(mouseName) > -1) {
  631. el.style.backgroundColor = draconicColor;
  632. if (el.className.indexOf(" complete ") < 0) {
  633. draconicCount++;
  634. if (draconicMice.indexOf(mouseName) == 3) {
  635. draconicHAICount++;
  636. } else if (draconicMice.indexOf(mouseName) == 4) {
  637. draconicBossCount++;
  638. } else if (draconicMice.indexOf(mouseName) == 5) {
  639. draconicSPCount++;
  640. }
  641. } else {
  642. if (isChecked) el.style.backgroundColor = "white";
  643. }
  644. } else if (lawMice.indexOf(mouseName) > -1) {
  645. el.style.backgroundColor = lawColor;
  646. if (el.className.indexOf(" complete ") < 0) {
  647. lawCount++;
  648. if (lawMice.indexOf(mouseName) == 3) {
  649. lawHAICount++;
  650. } else if (lawMice.indexOf(mouseName) == 4) {
  651. lawBossCount++;
  652. } else if (lawMice.indexOf(mouseName) == 5) {
  653. lawSPCount++;
  654. }
  655. } else {
  656. if (isChecked) el.style.backgroundColor = "white";
  657. }
  658. } else if (physicalMice.indexOf(mouseName) > -1) {
  659. el.style.backgroundColor = physicalColor;
  660. if (el.className.indexOf(" complete ") < 0) {
  661. physicalCount++;
  662. if (physicalMice.indexOf(mouseName) == 3) {
  663. physicalHAICount++;
  664. } else if (physicalMice.indexOf(mouseName) == 4) {
  665. physicalBossCount++;
  666. } else if (physicalMice.indexOf(mouseName) == 5) {
  667. physicalSPCount++;
  668. }
  669. } else {
  670. if (isChecked) el.style.backgroundColor = "white";
  671. }
  672. } else if (tacticalMice.indexOf(mouseName) > -1) {
  673. el.style.backgroundColor = tacticalColor;
  674. if (el.className.indexOf(" complete ") < 0) {
  675. tacticalCount++;
  676. if (tacticalMice.indexOf(mouseName) == 3) {
  677. tacticalHAICount++;
  678. } else if (tacticalMice.indexOf(mouseName) == 4) {
  679. tacticalBossCount++;
  680. } else if (tacticalMice.indexOf(mouseName) == 5) {
  681. tacticalSPCount++;
  682. }
  683. } else {
  684. if (isChecked) el.style.backgroundColor = "white";
  685. }
  686. } else if (pirateMice.indexOf(mouseName) > -1) {
  687. el.style.backgroundColor = pirateColor;
  688. if (el.className.indexOf(" complete ") < 0) {
  689. pirateCount++;
  690. if (pirateMice.indexOf(mouseName) == 6) {
  691. pirateSPCount++;
  692. } else if (pirateMice.indexOf(mouseName) < 3) {
  693. pirateT1Count++;
  694. } else {
  695. pirateT2Count++;
  696. }
  697. } else {
  698. if (isChecked) el.style.backgroundColor = "white";
  699. }
  700. } else if (richMice.indexOf(mouseName) > -1) {
  701. el.style.backgroundColor = richColor;
  702. if (el.className.indexOf(" complete ") < 0) {
  703. richCount++;
  704. if (richMice.indexOf(mouseName) == 1) {
  705. richSPCount++;
  706. }
  707. } else {
  708. if (isChecked) el.style.backgroundColor = "white";
  709. }
  710. } else if (wardenMice.indexOf(mouseName) > -1) {
  711. el.style.backgroundColor = wardenColor;
  712. if (el.className.indexOf(" complete ") < 0) {
  713. wardenCount++;
  714. if (wardenMice.indexOf(mouseName) == 0) {
  715. wardenRainCount++;
  716. } else if (wardenMice.indexOf(mouseName) == 1) {
  717. wardenFogCount++;
  718. } else if (wardenMice.indexOf(mouseName) == 2) {
  719. wardenFrostCount++;
  720. } else if (wardenMice.indexOf(mouseName) == 3) {
  721. wardenWindCount++;
  722. }
  723. } else {
  724. if (isChecked) el.style.backgroundColor = "white";
  725. }
  726. } else if (launchPadMice.indexOf(mouseName) > -1) {
  727. el.style.backgroundColor = launchPadColor;
  728. if (el.className.indexOf(" complete ") < 0) {
  729. launchPadCount++;
  730. if (launchPadMice.indexOf(mouseName) == 3) {
  731. launchPadSBCount++;
  732. }
  733. } else {
  734. if (isChecked) el.style.backgroundColor = "white";
  735. }
  736. }
  737. });
  738.  
  739. powerHAICount =
  740. arcaneHAICount +
  741. forgottenHAICount +
  742. hydroHAICount +
  743. shadowHAICount +
  744. draconicHAICount +
  745. lawHAICount +
  746. physicalHAICount +
  747. tacticalHAICount;
  748. powerBossCount =
  749. arcaneBossCount +
  750. forgottenBossCount +
  751. hydroBossCount +
  752. shadowBossCount +
  753. draconicBossCount +
  754. lawBossCount +
  755. physicalBossCount +
  756. tacticalBossCount;
  757. powerSPCount =
  758. arcaneSPCount +
  759. forgottenSPCount +
  760. hydroSPCount +
  761. shadowSPCount +
  762. draconicSPCount +
  763. lawSPCount +
  764. physicalSPCount +
  765. tacticalSPCount;
  766. allSPCount = powerSPCount + pirateSPCount + richSPCount;
  767.  
  768. // Remove existing birthday Map related elements before proceeding
  769. document.querySelectorAll(".tsitu-birthday-map").forEach((el) => el.remove());
  770.  
  771. const masterDiv = document.createElement("div");
  772. masterDiv.className = "tsitu-birthday-map";
  773. masterDiv.style =
  774. "display: inline-flex; margin-bottom: 10px; width: 100%; text-align: center; line-height: 1.5; overflow: hidden";
  775. const spanStyle =
  776. "; width: auto; padding: 5px; color: black; font-weight; font-size: 12.75px; text-shadow: 0px 0px 11px white";
  777.  
  778. const guardSpan = document.createElement("span");
  779. guardSpan.style = "background-color: " + guardColor + spanStyle;
  780. guardSpan.innerHTML = "Guard<br>" + guardCount;
  781. let guardSpanExtra = "";
  782. if (guardAppraiserCount > 0) {
  783. guardSpanExtra = guardSpanExtra + "<br>Appr (G)";
  784. }
  785. if (guardTinkererCount > 0) {
  786. guardSpanExtra = guardSpanExtra + "<br>Tink (J)";
  787. }
  788. if (guardGeologistCount > 0) {
  789. guardSpanExtra = guardSpanExtra + "<br>Geo (S)";
  790. }
  791. if (guardEmpressCount > 0) {
  792. guardSpanExtra = guardSpanExtra + "<br>Emp";
  793. }
  794. if (guardSpanExtra != "") {
  795. guardSpan.innerHTML = guardSpan.innerHTML + guardSpanExtra;
  796. }
  797.  
  798. const arcaneSpan = createSpan(
  799. arcaneColor,
  800. spanStyle,
  801. "Arc",
  802. arcaneCount,
  803. arcaneSPCount,
  804. arcaneBossCount,
  805. arcaneHAICount,
  806. allSPCount,
  807. powerBossCount,
  808. powerHAICount
  809. );
  810. const forgottenSpan = createSpan(
  811. forgottenColor,
  812. spanStyle,
  813. "Forg",
  814. forgottenCount,
  815. forgottenSPCount,
  816. forgottenBossCount,
  817. forgottenHAICount,
  818. allSPCount,
  819. powerBossCount,
  820. powerHAICount
  821. );
  822. const hydroSpan = createSpan(
  823. hydroColor,
  824. spanStyle,
  825. "Hydro",
  826. hydroCount,
  827. hydroSPCount,
  828. hydroBossCount,
  829. hydroHAICount,
  830. allSPCount,
  831. powerBossCount,
  832. powerHAICount
  833. );
  834. const shadowSpan = createSpan(
  835. shadowColor,
  836. spanStyle,
  837. "Shad",
  838. shadowCount,
  839. shadowSPCount,
  840. shadowBossCount,
  841. shadowHAICount,
  842. allSPCount,
  843. powerBossCount,
  844. powerHAICount
  845. );
  846. const draconicSpan = createSpan(
  847. draconicColor,
  848. spanStyle,
  849. "Draco",
  850. draconicCount,
  851. draconicSPCount,
  852. draconicBossCount,
  853. draconicHAICount,
  854. allSPCount,
  855. powerBossCount,
  856. powerHAICount
  857. );
  858. const lawSpan = createSpan(
  859. lawColor,
  860. spanStyle,
  861. "Law",
  862. lawCount,
  863. lawSPCount,
  864. lawBossCount,
  865. lawHAICount,
  866. allSPCount,
  867. powerBossCount,
  868. powerHAICount
  869. );
  870. const physicalSpan = createSpan(
  871. physicalColor,
  872. spanStyle,
  873. "Phy",
  874. physicalCount,
  875. physicalSPCount,
  876. physicalBossCount,
  877. physicalHAICount,
  878. allSPCount,
  879. powerBossCount,
  880. powerHAICount
  881. );
  882. const tacticalSpan = createSpan(
  883. tacticalColor,
  884. spanStyle,
  885. "Tac",
  886. tacticalCount,
  887. tacticalSPCount,
  888. tacticalBossCount,
  889. tacticalHAICount,
  890. allSPCount,
  891. powerBossCount,
  892. powerHAICount
  893. );
  894. const pirateSpan = createSpan(
  895. pirateColor,
  896. spanStyle,
  897. "Pirate",
  898. pirateCount,
  899. pirateSPCount,
  900. 0,
  901. 0,
  902. allSPCount,
  903. powerBossCount,
  904. powerHAICount
  905. );
  906. const richSpan = createSpan(
  907. richColor,
  908. spanStyle,
  909. "Rich",
  910. richCount,
  911. richSPCount,
  912. 0,
  913. 0,
  914. allSPCount,
  915. powerBossCount,
  916. powerHAICount
  917. );
  918.  
  919. const wardenSpan = document.createElement("span");
  920. wardenSpan.style = "background-color: " + wardenColor + spanStyle;
  921. wardenSpan.innerHTML = "Ward<br>" + wardenCount;
  922.  
  923. const launchPadSpan = document.createElement("span");
  924. launchPadSpan.style = "background-color: " + launchPadColor + spanStyle;
  925. launchPadSpan.innerHTML = "LP<br>" + launchPadCount;
  926. if (launchPadSBCount > 0) {
  927. launchPadSpan.innerHTML = launchPadSpan.innerHTML + "*";
  928. }
  929.  
  930. // Highlight uncaught only feature
  931. const highlightLabel = document.createElement("label");
  932. highlightLabel.htmlFor = "tsitu-highlight-box";
  933. highlightLabel.innerText = "Highlight uncaught mice only";
  934.  
  935. const highlightBox = document.createElement("input");
  936. highlightBox.type = "checkbox";
  937. highlightBox.name = "tsitu-highlight-box";
  938. highlightBox.style.verticalAlign = "middle";
  939. highlightBox.checked = isChecked;
  940. highlightBox.addEventListener("click", function () {
  941. if (highlightBox.checked) {
  942. localStorage.setItem("highlightPref", "uncaught-only");
  943. } else {
  944. localStorage.setItem("highlightPref", "all");
  945. }
  946. colorize();
  947. });
  948.  
  949. const highlightDiv = document.createElement("div");
  950. highlightDiv.className = "tsitu-birthday-map";
  951. highlightDiv.style = "float: right; position: relative; z-index: 1";
  952. highlightDiv.appendChild(highlightBox);
  953. highlightDiv.appendChild(highlightLabel);
  954.  
  955. const copySniperListLabel = document.createElement("label");
  956. copySniperListLabel.htmlFor = "tsitu-highlight-box";
  957. copySniperListLabel.innerText = "Copy Sniper List";
  958. if (copyFlag) {
  959. const snipeText = sniperList(
  960. arcaneCount,
  961. arcaneHAICount,
  962. arcaneBossCount,
  963. arcaneSPCount,
  964. forgottenCount,
  965. forgottenHAICount,
  966. forgottenBossCount,
  967. forgottenSPCount,
  968. hydroCount,
  969. hydroHAICount,
  970. hydroBossCount,
  971. hydroSPCount,
  972. shadowCount,
  973. shadowHAICount,
  974. shadowBossCount,
  975. shadowSPCount,
  976. draconicCount,
  977. draconicHAICount,
  978. draconicBossCount,
  979. draconicSPCount,
  980. lawCount,
  981. lawHAICount,
  982. lawBossCount,
  983. lawSPCount,
  984. physicalCount,
  985. physicalHAICount,
  986. physicalBossCount,
  987. physicalSPCount,
  988. tacticalCount,
  989. tacticalHAICount,
  990. tacticalBossCount,
  991. tacticalSPCount,
  992. pirateT1Count,
  993. pirateT2Count,
  994. pirateSPCount,
  995. richCount,
  996. richSPCount,
  997. guardAppraiserCount,
  998. guardTinkererCount,
  999. guardGeologistCount,
  1000. guardEmpressCount,
  1001. wardenRainCount,
  1002. wardenFogCount,
  1003. wardenFrostCount,
  1004. wardenWindCount,
  1005. powerSPCount,
  1006. powerBossCount
  1007. );
  1008. GM_setClipboard(snipeText);
  1009. }
  1010. const copySniperListSpan = document.createElement("span");
  1011. copySniperListSpan.className = "tsitu-birthday-map copnSniperList-span";
  1012. const copySniperLisTextSpan = document.createElement("span");
  1013. copySniperLisTextSpan.innerText = "Copy Sniper List";
  1014.  
  1015. const copySniperListButton = document.createElement("button");
  1016. copySniperListButton.className =
  1017. "mousehuntActionButton tiny tsitu-birthday-map";
  1018. copySniperListButton.style.cursor = "pointer";
  1019. copySniperListButton.style.fontSize = "9px";
  1020. copySniperListButton.style.padding = "2px";
  1021. copySniperListButton.style.margin = "0px 5px 5px 10px";
  1022. copySniperListButton.style.textShadow = "none";
  1023. copySniperListButton.style.display = "inline-block";
  1024. copySniperListButton.appendChild(copySniperLisTextSpan);
  1025.  
  1026. copySniperListButton.addEventListener("click", function () {
  1027. colorize("copySnipes");
  1028. });
  1029.  
  1030. copySniperListSpan.appendChild(copySniperListButton);
  1031.  
  1032. // Assemble masterDiv
  1033. if (guardCount > 0) {
  1034. masterDiv.appendChild(guardSpan);
  1035. }
  1036. if (arcaneCount > 0) {
  1037. masterDiv.appendChild(arcaneSpan);
  1038. }
  1039. if (forgottenCount > 0) {
  1040. masterDiv.appendChild(forgottenSpan);
  1041. }
  1042. if (hydroCount > 0) {
  1043. masterDiv.appendChild(hydroSpan);
  1044. }
  1045. if (shadowCount > 0) {
  1046. masterDiv.appendChild(shadowSpan);
  1047. }
  1048. if (draconicCount > 0) {
  1049. masterDiv.appendChild(draconicSpan);
  1050. }
  1051. if (lawCount > 0) {
  1052. masterDiv.appendChild(lawSpan);
  1053. }
  1054. if (physicalCount > 0) {
  1055. masterDiv.appendChild(physicalSpan);
  1056. }
  1057. if (tacticalCount > 0) {
  1058. masterDiv.appendChild(tacticalSpan);
  1059. }
  1060. if (pirateCount > 0) {
  1061. masterDiv.appendChild(pirateSpan);
  1062. }
  1063. if (richCount > 0) {
  1064. masterDiv.appendChild(richSpan);
  1065. }
  1066. if (wardenCount > 0) {
  1067. masterDiv.appendChild(wardenSpan);
  1068. }
  1069. if (launchPadCount > 0) {
  1070. masterDiv.appendChild(launchPadSpan);
  1071. }
  1072.  
  1073. // Inject into DOM
  1074. const insertEl = document.querySelector(
  1075. ".treasureMapView-leftBlock .treasureMapView-block-content"
  1076. );
  1077. if (
  1078. insertEl &&
  1079. document.querySelector(
  1080. ".treasureMapRootView-header-navigation-item.tasks.active"
  1081. )
  1082. ) {
  1083. insertEl.insertAdjacentElement("afterbegin", highlightDiv);
  1084. insertEl.insertAdjacentElement("afterbegin", masterDiv);
  1085. }
  1086.  
  1087. // Inject into DOM
  1088. const insertE2 = document.querySelector(
  1089. ".treasureMapView-leftBlock .treasureMapView-block-title"
  1090. );
  1091. if (
  1092. insertE2 &&
  1093. document.querySelector(
  1094. ".treasureMapRootView-header-navigation-item.tasks.active"
  1095. )
  1096. ) {
  1097. insertE2.insertAdjacentElement("beforeend", copySniperListSpan);
  1098. }
  1099. }
  1100.  
  1101. // Listen to XHRs, opening a map always at least triggers board.php
  1102. const originalOpen = XMLHttpRequest.prototype.open;
  1103. XMLHttpRequest.prototype.open = function () {
  1104. this.addEventListener("load", function () {
  1105. const mapEl = document.querySelector(".treasureMapView-mapMenu-rewardName");
  1106. if (mapEl) {
  1107. const mapName = mapEl.textContent;
  1108. if (mapName && spMaps.indexOf(mapName) > -1) {
  1109. colorize();
  1110. }
  1111. }
  1112. });
  1113. originalOpen.apply(this, arguments);
  1114. };

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址