Greasy Fork 还支持 简体中文。

DH3 FP Notification

Adds fight points notification

  1. // ==UserScript==
  2. // @name DH3 FP Notification
  3. // @namespace com.anwinity.dh3
  4. // @version 1.0.9
  5. // @description Adds fight points notification
  6. // @author Anwinity
  7. // @match dh3.diamondhunt.co
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. const FP_COSTS = {
  15. fields: 900,
  16. forest: 1800,
  17. caves: 3600,
  18. lavaDungeon: 5400,
  19. northernFields: 7200,
  20. cemetery: 9000,
  21. ocean: 10800,
  22. dungeon: 13200,
  23. dungeonHole: 25000
  24. };
  25.  
  26. const MAP_IDS = {
  27. fields: 1,
  28. forest: 2,
  29. caves: 2,
  30. lavaDungeon: 3,
  31. northernFields: 4,
  32. cemetery: 8,
  33. ocean: 10,
  34. dungeon: 16,
  35. dungeonHole: 17
  36. }
  37.  
  38. const scope = {
  39. area: "fields"
  40. };
  41.  
  42. function loadPreferences() {
  43. let area = localStorage.getItem("fp-notificiations.area") || "fields";
  44. scope.area = area;
  45. $("#fp-area").val(scope.area);
  46. }
  47.  
  48. function savePreferences() {
  49. localStorage.setItem("fp-notificiations.area", scope.area);
  50. }
  51.  
  52. function gotoArea() {
  53. if(scope.area == "full") {
  54. return;
  55. }
  56. clicksItem("fightMonsterButton");
  57. changeCombatMap(MAP_IDS[scope.area]);
  58. }
  59.  
  60. function fpNeeded() {
  61. if(scope.area == "full") {
  62. return parseInt(window.var_maxFightPoints);
  63. }
  64. let base = FP_COSTS[scope.area];
  65. let p = 1;
  66. if(window.var_cooldownRing1 == "1") {
  67. p -= 0.01;
  68. }
  69. if(window.var_cooldownRing2 == "1") {
  70. p -= 0.04;
  71. }
  72. if(window.var_cooldownRing3 == "1") {
  73. p -= 0.10;
  74. }
  75. if(window.var_cooldownRing4 == "1") {
  76. p -= 0.15;
  77. }
  78. return Math.ceil(base*p);
  79. }
  80.  
  81. function initUI() {
  82. const styles = document.createElement("style");
  83. styles.textContent = `
  84. span#notification-fightPoints {
  85. position: relative;
  86. }
  87. span#notification-fightPoints > #fp-area {
  88. position: absolute;
  89. bottom: 1px;
  90. right: 1px;
  91. margin: 0px;
  92. padding: 2px;
  93. background-color: rgba(1,1,1,0);
  94. border: 0px solid rgba(1,1,1,0);
  95. color: white;
  96. }
  97. span#notification-fightPoints > #fp-area > option {
  98. background-color: rgba(102, 0, 0, 0.9);
  99. }
  100. `;
  101. $("head").append(styles);
  102.  
  103. $("#notification-questsStarted").after(`
  104. <span id="notification-fightPoints" class="notification-red"">
  105. <img src="images/fightPoints.png" class="img-50">
  106. <span id="fp-timer"></span>
  107. <img id="fp-potion-active" src="images/combatCooldownPotion.png" style="height: 1em; display: none" title="Combat Cooldown Potion is active"></img>
  108. <select id="fp-area">
  109. <option value="fields">Fields</option>
  110. <option value="forest">Forest</option>
  111. <option value="caves">Caves</option>
  112. <option value="lavaDungeon">Lava</option>
  113. <option value="northernFields">N Fields</option>
  114. <option value="cemetery">Cemetery</option>
  115. <option value="ocean">Ocean</option>
  116. <option value="dungeon">Dungeon</option>
  117. <option value="dungeonHole">Dung. Hole</option>
  118. <option value="full">Full FP</option>
  119. </select>
  120. </span>
  121. `);
  122.  
  123. $("#notification-fightPoints").click(function() {
  124. gotoArea();
  125. });
  126. let areaSelect = $("span#notification-fightPoints > #fp-area");
  127. areaSelect.click(function(e) {
  128. e.stopPropagation();
  129. });
  130. areaSelect.change(function() {
  131. let area = $(this).val();
  132. scope.area = area;
  133. savePreferences();
  134. updateUI(window.var_fightPoints);
  135. });
  136. }
  137.  
  138. function updateUI(fp) {
  139. if(typeof fp === "string") {
  140. fp = parseInt(fp);
  141. }
  142. let fpPotion = parseInt(window.var_combatCooldownPotionTimer || "0") > 0;
  143. let fpMax = parseInt(window.var_maxFightPoints);
  144. let fpReq = fpNeeded();
  145. let count = Math.floor(fp / fpReq);
  146. let fpNext = fpReq * (count+1);
  147. if(fpNext > fpMax) {
  148. fpNext = fpMax;
  149. }
  150. let fpDelta = fpNext - fp;
  151. if(fpPotion) {
  152. fpDelta /= 2;
  153. $("#fp-potion-active").show();
  154. }
  155. else {
  156. $("#fp-potion-active").hide();
  157. }
  158. let time = fpDelta==0 ? "--:--" : formatTime(fpDelta);
  159. if(scope.area == "full") {
  160. $("#fp-timer").html(`${time}`);
  161. }
  162. else {
  163. $("#fp-timer").html(`${count}x&nbsp;&nbsp;${time}`);
  164. }
  165. }
  166.  
  167. function overrideFunctions() {
  168. const originalSetItems = window.setItems;
  169. window.setItems = function(data) {
  170. originalSetItems.apply(this, arguments);
  171. if(data) {
  172. let m = data.match(/fightPoints~(\d+)/);
  173. if(m) {
  174. updateUI(m[1]);
  175. }
  176. }
  177. }
  178. }
  179.  
  180. function init() {
  181. if(!window.var_username) {
  182. setTimeout(init, 1000);
  183. return;
  184. }
  185.  
  186. initUI();
  187. overrideFunctions();
  188. loadPreferences();
  189. }
  190.  
  191. $(init);
  192.  
  193. })();