IdlePixel+ Overview Panel

Single panel to control many skills

目前為 2023-12-20 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name IdlePixel+ Overview Panel
  3. // @namespace lbtechnology.info
  4. // @version 1.3.0
  5. // @description Single panel to control many skills
  6. // @author Lux-Ferre
  7. // @license MIT
  8. // @match *://idle-pixel.com/login/play*
  9. // @grant none
  10. // @require https://greasyfork.org/scripts/441206-idlepixel/code/IdlePixel+.js?anticache=20220905
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. class OverviewPlugin extends IdlePixelPlusPlugin {
  17. constructor() {
  18. super("overview", {
  19. about: {
  20. name: GM_info.script.name,
  21. version: GM_info.script.version,
  22. author: GM_info.script.author,
  23. description: GM_info.script.description
  24. },
  25. config: [
  26. {
  27. id: "colNum",
  28. label: "Number of modules per row",
  29. type: "integer",
  30. min: 1,
  31. max: 12,
  32. default: 3
  33. },
  34. {
  35. id: "farmingEnabled",
  36. label: "farmingEnabled",
  37. type: "boolean",
  38. default: true
  39. },
  40. {
  41. id: "gatheringEnabled",
  42. label: "gatheringEnabled",
  43. type: "boolean",
  44. default: true
  45. },
  46. {
  47. id: "mineralsEnabled",
  48. label: "mineralsEnabled",
  49. type: "boolean",
  50. default: true
  51. },
  52. {
  53. id: "woodcuttingEnabled",
  54. label: "woodcuttingEnabled",
  55. type: "boolean",
  56. default: true
  57. },
  58. {
  59. id: "smeltingEnabled",
  60. label: "smeltingEnabled",
  61. type: "boolean",
  62. default: true
  63. },
  64. {
  65. id: "cookingEnabled",
  66. label: "cookingEnabled",
  67. type: "boolean",
  68. default: true
  69. },
  70. {
  71. id: "brewingEnabled",
  72. label: "brewingEnabled",
  73. type: "boolean",
  74. default: true
  75. },
  76. {
  77. id: "fishingEnabled",
  78. label: "fishingEnabled",
  79. type: "boolean",
  80. default: false
  81. },
  82. {
  83. id: "machineryEnabled",
  84. label: "machineryEnabled",
  85. type: "boolean",
  86. default: false
  87. }
  88. ]
  89. });
  90. this.previous = "";
  91. }
  92.  
  93. onConfigsChanged() {
  94. this.applyConfigs()
  95. }
  96.  
  97. onLogin() {
  98. const onlineCount = $(".top-bar .gold:not(#top-bar-admin-link)");
  99. onlineCount.before(`
  100. <a href="#" class="hover float-end link-no-decoration"
  101. onclick="event.preventDefault(); IdlePixelPlus.setPanel('overview')"
  102. title="Overview">Overview&nbsp;&nbsp;&nbsp;
  103. </a>
  104. `);
  105.  
  106. this.addStyles()
  107. this.createPanel()
  108. this.addBonemealbinToPanel()
  109. this.addMeteorsToPanel()
  110. this.toggleMultiHarvest()
  111. this.addGatheringAreasToPanel()
  112. this.highlightGathering()
  113. this.applyConfigs()
  114.  
  115. const standardItemBoxes = {
  116. overviewLogsContainer: {
  117. itemList: ["logs", "oak_logs", "willow_logs", "maple_logs", "stardust_logs", "pine_logs", "redwood_logs", "dense_logs"],
  118. onClickString: "IdlePixelPlus.plugins['overview'].clicksLogs(this.getAttribute('ov-data-item'))",
  119. onContextMenu: ""
  120. },
  121. overviewBonemealContainer: {
  122. itemList: ["bones", "big_bones", "ice_bones", "blood_bones", "dragon_bones", "ashes"],
  123. onClickString: "IdlePixelPlus.plugins['overview'].clicksBones(this.getAttribute('ov-data-item'), 'left')",
  124. onContextMenu: "IdlePixelPlus.plugins['overview'].clicksBones(this.getAttribute('ov-data-item'), 'right'); return false;"
  125. },
  126. overviewSeedsContainer: {
  127. itemList: [
  128. "dotted_green_leaf_seeds", "green_leaf_seeds", "lime_leaf_seeds", "gold_leaf_seeds",
  129. "crystal_leaf_seeds", "red_mushroom_seeds", "stardust_seeds", "tree_seeds", "oak_tree_seeds",
  130. "willow_tree_seeds", "maple_tree_seeds", "stardust_tree_seeds", "pine_tree_seeds", "redwood_tree_seeds",
  131. "apple_tree_seeds", "banana_tree_seeds", "orange_tree_seeds", "palm_tree_seeds", "dragon_fruit_tree_seeds",
  132. "bone_tree_seeds", "lava_tree_seeds", "strange_tree_seeds", "potato_seeds", "carrot_seeds", "beet_seeds", "broccoli_seeds"
  133. ],
  134. onClickString: "IdlePixelPlus.plugins['overview'].clicksSeeds(this.getAttribute('ov-data-item'), 'left')",
  135. onContextMenu: "IdlePixelPlus.plugins['overview'].clicksSeeds(this.getAttribute('ov-data-item'), 'right'); return false;"
  136. },
  137. overviewBarsContainer: {
  138. itemList: ["bronze_bar", "iron_bar", "silver_bar", "gold_bar", "promethium_bar", "titanium_bar", "ancient_bar", "dragon_bar"],
  139. onClickString: "Modals.open_stardust_or_sell_item_dialogue('crafting', this.getAttribute('ov-data-item'))",
  140. onContextMenu: "IdlePixelPlus.plugins['overview'].rightClicksBars(this.getAttribute('ov-data-item')); return false;"
  141. },
  142. overviewOresContainer: {
  143. itemList: ["stone", "copper", "iron", "silver", "gold", "promethium", "titanium", "ancient_ore", "dragon_ore"],
  144. onClickString: "Modals.open_stardust_or_sell_item_dialogue('mining', this.getAttribute('ov-data-item'))",
  145. onContextMenu: ""
  146. },
  147. overviewRecipeContainer: {
  148. itemList: ["dotted_salad", "chocolate_cake", "lime_leaf_salad", "golden_apple", "banana_jello", "orange_pie", "pancakes", "coconut_stew", "dragon_fruit_salad",
  149. "potato_shake", "carrot_shake", "beet_shake", "broccoli_shake"],
  150. onClickString: "IdlePixelPlus.plugins['overview'].clicksRecipe(this.getAttribute('ov-data-item'), 'left')",
  151. onContextMenu: "IdlePixelPlus.plugins['overview'].clicksRecipe(this.getAttribute('ov-data-item'), 'right'); return false;"
  152. },
  153. overviewGatheringBagsContainer: {
  154. itemList: ["gathering_loot_bag_mines", "gathering_loot_bag_fields", "gathering_loot_bag_forest", "gathering_loot_bag_fishing_pond",
  155. "gathering_loot_bag_kitchen", "gathering_loot_bag_gem_mine", "gathering_loot_bag_castle", "gathering_loot_bag_junk"],
  156. onClickString: "IdlePixelPlus.plugins['overview'].clicksBags(this.getAttribute('ov-data-item'), 'left')",
  157. onContextMenu: "IdlePixelPlus.plugins['overview'].clicksBags(this.getAttribute('ov-data-item'), 'right'); return false;"
  158. },
  159. overviewGemContainer: {
  160. itemList: ["sapphire", "emerald", "ruby", "diamond", "blood_diamond"],
  161. onClickString: "",
  162. onContextMenu: ""
  163. },
  164. overviewSDCrystalContainer: {
  165. itemList: ["small_stardust_prism", "medium_stardust_prism", "large_stardust_prism", "huge_stardust_prism"],
  166. onClickString: "IdlePixelPlus.plugins['overview'].clicksSDCrystals(this.getAttribute('ov-data-item'), 'left')",
  167. onContextMenu: "IdlePixelPlus.plugins['overview'].clicksSDCrystals(this.getAttribute('ov-data-item'), 'right'); return false;"
  168. },
  169. overviewGeodeContainer: {
  170. itemList: ["grey_geode", "blue_geode", "green_geode", "red_geode", "cyan_geode", "ancient_geode"],
  171. onClickString: "IdlePixelPlus.plugins['overview'].clicksGeode(this.getAttribute('ov-data-item'), 'left')",
  172. onContextMenu: "IdlePixelPlus.plugins['overview'].clicksGeode(this.getAttribute('ov-data-item'), 'right'); return false;"
  173. },
  174. overviewMineralContainer: {
  175. itemList: ["blue_marble_mineral", "amethyst_mineral", "sea_crystal_mineral", "dense_marble_mineral", "fluorite_mineral", "clear_marble_mineral",
  176. "jade_mineral", "lime_quartz_mineral", "opal_mineral", "purple_quartz_mineral", "amber_mineral", "smooth_pearl_mineral",
  177. "sulfer_mineral", "topaz_mineral", "tanzanite_mineral", "magnesium_mineral", "frozen_mineral", "blood_crystal_mineral"],
  178. onClickString: "IdlePixelPlus.plugins['overview'].clicksMineral(this.getAttribute('ov-data-item'), 'left')",
  179. onContextMenu: "IdlePixelPlus.plugins['overview'].clicksMineral(this.getAttribute('ov-data-item'), 'right'); return false;"
  180. },
  181. overviewPotionContainer: {
  182. itemList: ["stardust_potion", "energy_potion", "anti_disease_potion", "tree_speed_potion", "smelting_upgrade_potion", "great_stardust_potion", "farming_speed_potion",
  183. "rare_monster_potion", "super_stardust_potion", "gathering_unique_potion", "heat_potion", "bait_potion", "bone_potion", "furnace_speed_potion", "promethium_potion",
  184. "super_rare_monster_potion", "ultra_stardust_potion", "cooks_dust_potion", "fighting_dust_potion", "tree_dust_potion", "farm_dust_potion",
  185. "magic_shiny_crystal_ball_potion", "birdhouse_potion", "rocket_potion", "titanium_potion", "blue_orb_potion", "geode_potion", "magic_crystal_ball_potion",
  186. "stone_converter_potion", "rain_potion", "combat_loot_potion", "rotten_potion", "merchant_speed_potion", "green_orb_potion", "ancient_potion", "guardian_key_potion",
  187. "red_orb_potion"],
  188. onClickString: "IdlePixelPlus.plugins['overview'].clicksPotion(this.getAttribute('ov-data-item'))",
  189. onContextMenu: "IdlePixelPlus.plugins['overview'].rightClicksPotion(this.getAttribute('ov-data-item')); return false;"
  190. }
  191. /*,
  192. template: {
  193. itemList: [],
  194. onClickString: "",
  195. onContextMenu: ""
  196. }*/
  197. }
  198.  
  199. for (const [containerId, itemData] of Object.entries(standardItemBoxes)) {
  200. this.addStandardItemsToPanel(containerId, itemData)
  201. }
  202. }
  203.  
  204. onMessageReceived(data) {
  205. if(Globals.currentPanel !== "panel-overview"){return;}
  206. if (data.startsWith("SET_ITEMS")){
  207. this.updatePanelTrees()
  208. this.updatePanelPlants()
  209. this.updatePanelCooking()
  210. this.updateSmeltingPanel()
  211. }
  212. }
  213.  
  214. addStyles(){
  215. let borderColour
  216.  
  217. if ("ui-tweaks" in IdlePixelPlus.plugins){
  218. borderColour = IdlePixelPlus.plugins["ui-tweaks"].config["font-color-panels"]
  219. } else {
  220. borderColour = "black"
  221. }
  222.  
  223. $("head").append(`
  224. <style id="styles-overview">
  225. .overviewSkillModule {
  226. border-radius: 3px;
  227. border-style: outset;
  228. }
  229. .overviewGatheringBoxArea {
  230. width: 150px;
  231. height: 150px;
  232. border-radius: 30px;
  233. }
  234. .overviewGatheringBoxSelected {
  235. box-shadow: 0 0 15px #80ed6f;
  236. }
  237. .overviewDottedBorder {
  238. border-radius: 2px;
  239. border: 1px dotted ${borderColour};
  240. }
  241. </style>
  242. `)
  243. }
  244.  
  245. createPanel(){
  246. IdlePixelPlus.addPanel("overview", "Overview", function() {
  247. const content = `
  248. <div id="overviewTopLevelRow" class="row row-cols-3 d-flex flex-wrap">
  249. <div id="overviewFarmingModule" class="col overviewSkillModule">
  250. <div id="overviewBonemealContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  251. <div id="overviewSeedsContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  252. <div id="overviewFarmingPlotContainer" class="row farming-patches-area g-0 overviewDottedBorder">
  253. <div id="overviewFarmingPlot-1" class="col text-center d-flex flex-column align-items-center"><img id="overviewFarmingPatchImg-1" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Farming.clicksPlot(1)" /><label id="overviewFarmingTimer-1" class="form-label">0</label></div>
  254. <div id="overviewFarmingPlot-2" class="col text-center d-flex flex-column align-items-center"><img id="overviewFarmingPatchImg-2" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Farming.clicksPlot(2)" /><label id="overviewFarmingTimer-2" class="form-label">0</label></div>
  255. <div id="overviewFarmingPlot-3" class="col text-center d-flex flex-column align-items-center"><img id="overviewFarmingPatchImg-3" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Farming.clicksPlot(3)" /><label id="overviewFarmingTimer-3" class="form-label">0</label></div>
  256. <div id="overviewFarmingPlot-4" class="col text-center d-flex flex-column align-items-center"><img id="overviewFarmingPatchImg-4" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Farming.clicksPlot(4)" /><label id="overviewFarmingTimer-4" class="form-label">0</label></div>
  257. <div id="overviewFarmingPlot-5" class="col text-center d-flex flex-column align-items-center"><img id="overviewFarmingPatchImg-5" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Farming.clicksPlot(5)" /><label id="overviewFarmingTimer-5" class="form-label">0</label></div>
  258. </div>
  259. <div class="row">
  260. <div class="col text-center overviewDottedBorder"><button id="overviewHarvestAll" class="btn btn-primary" type="button" onclick="IdlePixelPlus.plugins.slapchop.quickHarvest()">Harvest All</button></div>
  261. </div>
  262. </div>
  263. <div id="overviewGatheringModule" class="col overviewSkillModule">
  264. <div id="overviewGatheringBagsContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  265. <div id="overviewGatheringAreasContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  266. </div>
  267. <div id="overviewMineralModule" class="col overviewSkillModule">
  268. <div id="overviewGemContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  269. <div id="overviewSDCrystalContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  270. <div id="overviewGeodeContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  271. <div id="overviewMineralContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  272. </div>
  273. <div id="overviewWoodcuttingModule" class="col overviewSkillModule">
  274. <div class="row">
  275. <div class="col-lg-3 overviewDottedBorder">
  276. <div>
  277. <div class="form-check"><input id="overviewUseLogsNone" class="form-check-input" type="radio" checked name="overviewUseLogsType" value="none" /><label class="form-check-label" for="overviewUseLogsNone">None</label></div>
  278. <div class="form-check"><input id="overviewUseLogsHeat" class="form-check-input" type="radio" name="overviewUseLogsType" value="heat" /><label class="form-check-label" for="overviewUseLogsHeat">Heat</label></div>
  279. <div class="form-check"><input id="overviewUseLogsCharcoal" class="form-check-input" type="radio" name="overviewUseLogsType" value="charcoal" /><label class="form-check-label" for="overviewUseLogsCharcoal">Charcoal</label></div>
  280. </div>
  281. </div>
  282. <div class="col">
  283. <div id="overviewLogsContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  284. </div>
  285. </div>
  286. <div id="overviewWCPlotContainer" class="row farming-patches-area g-0 overviewDottedBorder">
  287. <div id="overviewWCPlot-1" class="col text-center d-flex flex-column align-items-center"><img id="overviewWoodcuttingPatchImg-1" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Woodcutting.clicksPlot(1)" /><label id="overviewWoodcuttingTimer-1" class="form-label">0</label></div>
  288. <div id="overviewWCPlot-2" class="col text-center d-flex flex-column align-items-center"><img id="overviewWoodcuttingPatchImg-2" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Woodcutting.clicksPlot(2)" /><label id="overviewWoodcuttingTimer-2" class="form-label">0</label></div>
  289. <div id="overviewWCPlot-3" class="col text-center d-flex flex-column align-items-center"><img id="overviewWoodcuttingPatchImg-3" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Woodcutting.clicksPlot(3)" /><label id="overviewWoodcuttingTimer-3" class="form-label">0</label></div>
  290. <div id="overviewWCPlot-4" class="col text-center d-flex flex-column align-items-center"><img id="overviewWoodcuttingPatchImg-4" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Woodcutting.clicksPlot(4)" /><label id="overviewWoodcuttingTimer-4" class="form-label">0</label></div>
  291. <div id="overviewWCPlot-5" class="col text-center d-flex flex-column align-items-center"><img id="overviewWoodcuttingPatchImg-5" class="farming-patch" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png" width="75" onclick="Woodcutting.clicksPlot(5)" /><label id="overviewWoodcuttingTimer-5" class="form-label">0</label></div>
  292. </div>
  293. <div class="row">
  294. <div class="col text-center overviewDottedBorder"><button id="overviewChopAll" class="btn btn-primary" type="button" onclick="IdlePixelPlus.plugins.slapchop.quickChop()">Chop All</button></div>
  295. </div>
  296. </div>
  297. <div id="overviewSmeltingModule" class="col overviewSkillModule">
  298. <div class="row">
  299. <div class="col">
  300. <div class="row">
  301. <div class="col d-flex justify-content-between overviewDottedBorder"><label class="form-label">Oil</label><label id="overviewOilNum" class="form-label">0</label></div>
  302. </div>
  303. <div class="row">
  304. <div class="col d-flex justify-content-between overviewDottedBorder"><label class="form-label">Lava</label><label id="overviewLavaNum" class="form-label">0</label></div>
  305. </div>
  306. <div class="row">
  307. <div class="col d-flex justify-content-between overviewDottedBorder"><label class="form-label">Buckets</label><label id="overviewBucketsNum" class="form-label">0</label></div>
  308. </div>
  309. </div>
  310. <div class="col text-center align-self-center"><img id="overviewFurnaceIcon" src="https://idlepixel.s3.us-east-2.amazonaws.com/images/promethium_furnace.png" onclick="Modals.open_furnace_dialogue()" /></div>
  311. <div class="col">
  312. <div class="row">
  313. <div class="col d-flex justify-content-between overviewDottedBorder"><label class="form-label">Charcoal</label><label id="overviewCharcoalNum" class="form-label">0</label></div>
  314. </div>
  315. <div class="row">
  316. <div class="col d-flex justify-content-between overviewDottedBorder"><label class="form-label">Plasma</label><label id="overviewPlasmaNum" class="form-label">0</label></div>
  317. </div>
  318. <div class="row">
  319. <div class="col d-flex justify-content-between overviewDottedBorder"><label class="form-label">D. Fire</label><label id="overviewDFireNum" class="form-label">0</label></div>
  320. </div>
  321. </div>
  322. </div>
  323. <div id="overviewBarsContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  324. <div id="overviewOresContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  325. </div>
  326. <div id="overviewCookingModule" class="col overviewSkillModule">
  327. <div class="row">
  328. <div class="col-xl-4 text-center align-self-center overviewDottedBorder"><img id="overviewCooksBookItem" style="width: 100px;height: 100px;" onclick="IdlePixelPlus.plugins[&#39;overview&#39;].clicksCooksBook(&#39;left&#39;)" oncontextmenu="IdlePixelPlus.plugins[&#39;overview&#39;].clicksCooksBook(&#39;right&#39;); return false;" /></div>
  329. <div class="col text-center align-self-center overviewDottedBorder"><label id="overviewCooksBookTimer" class="col-form-label">0</label></div>
  330. </div>
  331. <div id="overviewRecipeContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  332. </div>
  333. <div id="overviewBrewingModule" class="col overviewSkillModule">
  334. <div id="overviewPotionContainer" class="row g-0 d-flex justify-content-evenly overviewDottedBorder"></div>
  335. </div>
  336. <div id="overviewFishingModule" class="col overviewSkillModule"></div>
  337. <div id="overviewMachineryModule" class="col overviewSkillModule"></div>
  338. </div>
  339. `
  340. return content
  341. });
  342. }
  343.  
  344. applyConfigs() {
  345. // Modules per row
  346. const colClass = "row-cols-" + this.getConfig("colNum")
  347. const topLevel = $("#overviewTopLevelRow")
  348.  
  349. for(let i = 0; i <= 12 ; i++) {
  350. const oldClass = `row-cols-${i}`
  351. topLevel.removeClass(oldClass)
  352. }
  353.  
  354. topLevel.addClass(colClass)
  355.  
  356. // Enable/disable modules
  357. const moduleList = [
  358. ["farmingEnabled", "overviewFarmingModule"],
  359. ["gatheringEnabled", "overviewGatheringModule"],
  360. ["mineralsEnabled", "overviewMineralModule"],
  361. ["woodcuttingEnabled", "overviewWoodcuttingModule"],
  362. ["smeltingEnabled", "overviewSmeltingModule"],
  363. ["cookingEnabled", "overviewCookingModule"],
  364. ["brewingEnabled", "overviewBrewingModule"],
  365. ["fishingEnabled", "overviewFishingModule"],
  366. ["machineryEnabled", "overviewMachineryModule"]
  367. ]
  368.  
  369. moduleList.forEach(module => {
  370. const moduleEnabled = this.getConfig(module[0])
  371.  
  372. const moduleLocation = $(`#${module[1]}`)
  373.  
  374. if (moduleEnabled){
  375. moduleLocation.show()
  376. } else {
  377. moduleLocation.hide()
  378. }
  379. })
  380. }
  381.  
  382. formatTimeWithDays(timeInSecs) {
  383. let timerStr = "";
  384. const hour24 = 24 * 60 * 60;
  385.  
  386. const timerDays = Math.floor(timeInSecs / hour24);
  387. if(timeInSecs > hour24) {
  388. timerStr = `${timerDays}d ${format_time(timeInSecs - (timerDays * hour24))}`
  389. } else {
  390. timerStr = `${format_time(timeInSecs - (timerDays * hour24))}`
  391. }
  392.  
  393. return timerStr;
  394. }
  395.  
  396. getFurnace(){
  397. const furnaceList = ["dragon_furnace", "ancient_furnace", "titanium_furnace", "promethium_furnace", "gold_furnace",
  398. "silver_furnace", "iron_furnace", "bronze_furnace", "stone_furnace"]
  399. for(let i = 0; i < furnaceList.length; i++) {
  400. const furnace = furnaceList[i]
  401. if(window["var_"+furnace]){
  402. return furnace
  403. }
  404. }
  405. return "";
  406. }
  407.  
  408. addStandardItemsToPanel(containerId, itemData){
  409. const itemList = itemData.itemList
  410. const itemOnClick = itemData.onClickString
  411. const itemRightClick = itemData.onContextMenu
  412.  
  413. itemList.forEach((itemType) => {
  414. const itemElementString = `<div class="col d-flex justify-content-center">
  415. <itembox data-item="playtime" ov-data-item="${itemType}" id="overview-itembox-${itemType}" onclick="${itemOnClick}" onContextMenu="${itemRightClick}" class="shadow hover">
  416. <div class="center mt-1"><img src="https://d1xsc8x7nc5q8t.cloudfront.net/images/${itemType}.png" title="${itemType}"></div>
  417. <div class="center mt-2"> <item-display data-format="number" data-key="${itemType}"></item-display></div>
  418. </itembox>
  419. </div>`
  420. const itemBox = $.parseHTML(itemElementString)
  421. $(`#${containerId}`).append(itemBox)
  422. })
  423. }
  424.  
  425. addGatheringAreasToPanel(){
  426. const areaData = [
  427. {
  428. id: "overviewGatheringBoxMines",
  429. background: "background-dark-grey",
  430. image: "gathering_mine.png",
  431. name: "mines"
  432. },
  433. {
  434. id: "overviewGatheringBoxFields",
  435. background: "background-dark-green",
  436. image: "gathering_field.png",
  437. name: "fields"
  438. },
  439. {
  440. id: "overviewGatheringBoxForest",
  441. background: "background-brown",
  442. image: "gathering_forest.png",
  443. name: "forest"
  444. },
  445. {
  446. id: "overviewGatheringBoxFishingPond",
  447. background: "background-dark-blue",
  448. image: "gathering_fishing_pond.png",
  449. name: "fishing_pond"
  450. },
  451. {
  452. id: "overviewGatheringBoxKitchen",
  453. background: "background-dark-orange",
  454. image: "gathering_kitchen.png",
  455. name: "kitchen"
  456. },
  457. {
  458. id: "overviewGatheringBoxGemMine",
  459. background: "background-dark-cyan",
  460. image: "gathering_gem_mine.png",
  461. name: "gem_mine"
  462. },
  463. {
  464. id: "overviewGatheringBoxCastle",
  465. background: "background-veryrare",
  466. image: "gathering_castle.png",
  467. name: "castle"
  468. }
  469. ]
  470.  
  471. areaData.forEach((area) => {
  472. const areaId = area.id
  473. const background = area.background
  474. const image = area.image
  475. const name = area.name
  476.  
  477. const areaElementString = `<div class="col d-flex justify-content-center">
  478. <div id="${areaId}" class="d-flex ${background} hover overviewGatheringBoxArea"
  479. ov-data-item="${name}" onclick="IdlePixelPlus.plugins['overview'].changeGatheringArea(this.getAttribute('ov-data-item'))">
  480. <img class="m-auto w-80 h-80" src="https://d1xsc8x7nc5q8t.cloudfront.net/images/${image}" />
  481. </div>
  482. </div>`
  483. const areaBox = $.parseHTML(areaElementString)
  484. $(`#overviewGatheringAreasContainer`).append(areaBox)
  485. })
  486. }
  487.  
  488. addMeteorsToPanel(){
  489. const meteorString = `
  490. <div class="col d-flex justify-content-center">
  491. <itembox data-item="playtime" ov-data-item="meteor" class="shadow hover itembox-resource-mining-1"
  492. onclick="Modals.open_image_modal('METEOR', 'images/meteor.png', 'Mine the material from the meteor?', 'Mine it!', 'Close', 'MINE_METEOR')"
  493. oncontextmenu="websocket.send('MINE_METEOR')"
  494. >
  495. <div class="center mt-1"><img draggable="false" src="https://d1xsc8x7nc5q8t.cloudfront.net/images/meteor.png" title="meteor"></div>
  496. <div class="center mt-2"><item-display data-format="number" data-key="meteor">0</item-display></div>
  497. </itembox>
  498. </div>`
  499.  
  500. const meteorBox = $.parseHTML(meteorString)
  501. $("#overviewGeodeContainer").append(meteorBox)
  502. }
  503.  
  504. addBonemealbinToPanel(){
  505. const binString = `
  506. <div class="col d-flex justify-content-center">
  507. <itembox data-item="playtime" ov-data-item="bonemeal_bin" class="shadow hover bone-item-box">
  508. <div class="center mt-1"><img draggable="false" src="https://d1xsc8x7nc5q8t.cloudfront.net/images/bonemeal_bin.png" title="bonemeal_bin"></div>
  509. <div class="center mt-2"> <img src="https://d1xsc8x7nc5q8t.cloudfront.net/images/bonemeal_icon.png"> <item-display data-format="number" data-key="bonemeal">0</item-display></div>
  510. </itembox>
  511. </div>`
  512.  
  513. const bonemealBox = $.parseHTML(binString)
  514. $("#overviewBonemealContainer").append(bonemealBox)
  515. }
  516.  
  517. toggleMultiHarvest(){
  518. if (!("slapchop" in IdlePixelPlus.plugins)){
  519. $("#overviewChopAll").hide()
  520. $("#overviewHarvestAll").hide()
  521. }
  522. }
  523.  
  524. updatePanelTrees(){
  525. for(let i = 1; i < 6; i++) {
  526. const tree = Items.getItemString("tree_" + i);
  527. const stage = Items.getItem("tree_stage_" + i);
  528. const tree_time = Items.getItem("tree_timer_"+ i)
  529. let time_string
  530.  
  531. if(tree_time===0){
  532. time_string = "EMPTY"
  533. } else if (tree_time===1){
  534. time_string = "READY"
  535. } else {
  536. time_string = this.formatTimeWithDays(tree_time)
  537. }
  538.  
  539. $(`#overviewWoodcuttingTimer-${i}`).html(time_string)
  540.  
  541. let img_url
  542.  
  543. if(tree !== "none"){
  544. img_url = `https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_${tree}_${stage}.png`
  545. } else {
  546. if(i === 4 || i === 5){
  547. if(!DonorShop.has_donor_active(Items.getItem("donor_tree_patches_timestamp"))){
  548. img_url = `https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_locked.png`
  549. } else {
  550. img_url = `https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png`
  551. }
  552. } else {
  553. img_url = `https://idlepixel.s3.us-east-2.amazonaws.com/images/woodcutting_none.png`
  554. }
  555. }
  556. $(`#overviewWoodcuttingPatchImg-${i}`).attr("src", img_url)
  557. }
  558. }
  559.  
  560. updatePanelPlants(){
  561. for(let i = 1; i < 6; i++) {
  562. const crop = Items.getItemString("farm_" + i);
  563. const stage = Items.getItem("farm_stage_" + i);
  564. const crop_time = Items.getItem("farm_timer_"+ i)
  565. let time_string
  566.  
  567. if(crop_time===0){
  568. time_string = "EMPTY"
  569. } else if (crop_time===1){
  570. time_string = "READY"
  571. } else {
  572. time_string = this.formatTimeWithDays(crop_time)
  573. }
  574.  
  575. $(`#overviewFarmingTimer-${i}`).html(time_string)
  576.  
  577. let img_url
  578.  
  579. if(crop !== "none"){
  580. if (Items.getItem("farm_death_" + i) === 1){
  581. img_url = "https://idlepixel.s3.us-east-2.amazonaws.com/images/farming_dead_leaf.png"
  582. } else {
  583. img_url = `https://idlepixel.s3.us-east-2.amazonaws.com/images/farming_${crop}_${stage}.png`
  584. }
  585. } else {
  586. if(i === 4 || i === 5){
  587. if(!DonorShop.has_donor_active(Items.getItem("donor_tree_patches_timestamp"))){
  588. img_url = `https://idlepixel.s3.us-east-2.amazonaws.com/images/farming_locked.png`
  589. } else {
  590. img_url = `https://idlepixel.s3.us-east-2.amazonaws.com/images/farming_none.png`
  591. }
  592. } else {
  593. img_url = `https://idlepixel.s3.us-east-2.amazonaws.com/images/farming_none.png`
  594. }
  595. }
  596. $(`#overviewFarmingPatchImg-${i}`).attr("src", img_url)
  597. }
  598. }
  599.  
  600. updatePanelCooking() {
  601. let current_item = IdlePixelPlus.getVarOrDefault("cooks_book_item", "cooks_book", "string")
  602. if (current_item === "none"){current_item="cooks_book"}
  603.  
  604. const current_time = IdlePixelPlus.getVarOrDefault("cooks_book_timer", 0, "int")
  605. let formatted_time
  606. if (current_time<=1){
  607. formatted_time = "Completed."
  608. } else {
  609. formatted_time = this.formatTimeWithDays(current_time)
  610. }
  611.  
  612. $("#overviewCooksBookItem").attr("src", `https://d1xsc8x7nc5q8t.cloudfront.net/images/${current_item}.png`)
  613. $("#overviewCooksBookTimer").html(`${formatted_time}`)
  614. }
  615.  
  616. updateSmeltingPanel(){
  617. /*oil, lava, buckets, coal, plasma, fire, furnace, bar_click*/
  618. const oilNum = IdlePixelPlus.getVarOrDefault("oil", 0, "int")
  619. const lavaNum = IdlePixelPlus.getVarOrDefault("lava", 0, "int")
  620. const bucketsNum = IdlePixelPlus.getVarOrDefault("iron_bucket", 0, "int")
  621. const charcoalNum = IdlePixelPlus.getVarOrDefault("charcoal", 0, "int")
  622. const plasmaNum = IdlePixelPlus.getVarOrDefault("plasma", 0, "int")
  623. const dFireNum = IdlePixelPlus.getVarOrDefault("dragon_fire", 0, "int")
  624.  
  625. const furnaceType = this.getFurnace()
  626.  
  627. $("#overviewOilNum").html(oilNum)
  628. $("#overviewLavaNum").html(lavaNum)
  629. $("#overviewBucketsNum").html(bucketsNum)
  630. $("#overviewCharcoalNum").html(charcoalNum)
  631. $("#overviewPlasmaNum").html(plasmaNum)
  632. $("#overviewDFNum").html(dFireNum)
  633.  
  634. $("#overviewFurnaceIcon").attr("src", `https://idlepixel.s3.us-east-2.amazonaws.com/images/${furnaceType}.png`)
  635. }
  636.  
  637. clicksLogs(logType){
  638. const action = $('input[name=overviewUseLogsType]:checked').val();
  639. if (action === "none") {return;}
  640. if (action === "heat"){
  641. Modals.clicks_oven_log(logType)
  642. } else if (action === "charcoal"){
  643. if ("slapchop" in IdlePixelPlus.plugins){
  644. IdlePixelPlus.plugins.slapchop.quickFoundry(logType)
  645. } else {
  646. Modals.open_foundry_clicks_log(logType)
  647. }
  648. }
  649. }
  650.  
  651. clicksSeeds(seedType, clickType){
  652. let n = IdlePixelPlus.getVarOrDefault(seedType, 0, "int");
  653.  
  654. if(clickType==="left" && n>1) {
  655. n = 1;
  656. }
  657. const donor = DonorShop.has_donor_active(Items.getItem("donor_farm_patches_timestamp"));
  658. const maxPlot = donor ? 5 : 3;
  659. for(let plot = 1; plot <= maxPlot && n > 0; plot++) {
  660. if(IdlePixelPlus.getVar(`farm_${plot}`) === "none") {
  661. websocket.send(`PLANT=${seedType}~${plot}`);
  662. n--;
  663. }
  664. }
  665. }
  666.  
  667. rightClicksBars(barType){
  668. const oreBarMap = {
  669. bronze_bar: "copper",
  670. iron_bar: "iron",
  671. silver_bar: "silver",
  672. gold_bar: "gold",
  673. promethium_bar: "promethium",
  674. titanium_bar: "titanium",
  675. ancient_bar: "ancient_ore",
  676. dragon_bar: "dragon_ore"
  677. }
  678. if ("slapchop" in IdlePixelPlus.plugins){
  679. IdlePixelPlus.plugins.slapchop.quickSmelt(oreBarMap[barType])
  680. } else {
  681. Modals.open_stardust_or_sell_item_dialogue('crafting', barType)
  682. }
  683. }
  684.  
  685. clicksBags(bagType, clickType){
  686. const area = bagType.slice(19)
  687. const num = IdlePixelPlus.getVarOrDefault(bagType, 0, "int");
  688.  
  689. if (clickType === "left"){
  690. Modals.open_input_dialogue_with_value(area, 'Open', 'How many?', num, 'OPEN_GATHERING_LOOT')
  691. } else if (num > 0) {
  692. websocket.send(`OPEN_GATHERING_LOOT=${area}~${num}`);
  693. }
  694. }
  695.  
  696. clicksSDCrystals(crystalType, clickType){
  697. const num = IdlePixelPlus.getVarOrDefault(crystalType, 0, "int");
  698.  
  699. if (clickType === "left"){
  700. Modals.open_input_dialogue_with_value(crystalType, 'Smash', 'How many stardust prism do you want to smash?', num, 'SMASH_STARDUST_PRISM')
  701. } else if (num > 0 ){
  702. websocket.send(`SMASH_STARDUST_PRISM=${crystalType}~${num}`);
  703. }
  704. }
  705.  
  706. clicksGeode(geodeType, clickType){
  707. const num = IdlePixelPlus.getVarOrDefault(geodeType, 0, "int");
  708.  
  709. if (clickType === "left"){
  710. Modals.open_input_dialogue_with_value(geodeType, 'Open', 'How many geodes to you want to crack?', num, 'CRACK_GEODE')
  711. } else if (num > 0 ){
  712. websocket.send(`CRACK_GEODE=${geodeType}~${num}`)
  713. }
  714. }
  715.  
  716. clicksMineral(mineralType, clickType){
  717. const num = IdlePixelPlus.getVarOrDefault(mineralType, 0, "int");
  718.  
  719. if (clickType === "left"){
  720. Modals.clicks_mineral(mineralType)
  721. } else if (num > 0 ){
  722. websocket.send(`MINERAL_XP=${mineralType}~${num}`)
  723. }
  724. }
  725.  
  726. clicksBones(boneType, clickType){
  727. const num = IdlePixelPlus.getVarOrDefault(boneType, 0, "int");
  728.  
  729. if (clickType === "left"){
  730. Farming.clicks_bones(boneType)
  731. } else if (num > 0 ){
  732. websocket.send(`ADD_BONEMEAL=${boneType}~${num}`);
  733. }
  734. }
  735.  
  736. clicksCooksBook(clickType){
  737. const currentRecipe = IdlePixelPlus.getVarOrDefault("cooks_book_item", "none", "string")
  738. if (currentRecipe==="none"){return;}
  739.  
  740. websocket.send("COOKS_BOOK_READY")
  741.  
  742. if (clickType === "left"){return;}
  743.  
  744. websocket.send(`COOKS_BOOK=${currentRecipe}`)
  745. }
  746.  
  747. clicksRecipe(recipe, clickType){
  748. if (clickType === "right"){
  749. websocket.send("COOKS_BOOK_READY")
  750. }
  751.  
  752. websocket.send(`COOKS_BOOK=${recipe}`)
  753. }
  754.  
  755. clicksPotion(potionType){
  756. websocket.send(`BREW=${potion}~1`)
  757. }
  758.  
  759. rightClicksPotion(potionType){
  760. const potionCount = IdlePixelPlus.getVarOrDefault(potionType, 0, "int")
  761.  
  762. if (potionCount<1){return;}
  763.  
  764. switch(potionType){
  765. case "combat_loot_potion":
  766. if (window["var_combat_loot_potion_timer"] === "0"){
  767. websocket.send(`BREWING_DRINK_COMBAT_LOOT_POTION`);
  768. }
  769. break;
  770. case "rotten_potion":
  771. if (window["var_rotten_potion_timer"] === "0"){
  772. websocket.send(`BREWING_DRINK_ROTTEN_POTION`);
  773. }
  774. break;
  775. case "merchant_speed_potion":
  776. if (window["var_merchant_speed_potion_timer"] === "0"){
  777. websocket.send(`BREWING_DRINK_MERCHANT_SPEED_POTION`);
  778. }
  779. break;
  780. default:
  781. websocket.send(`DRINK=${potionType}`);
  782. break;
  783. }
  784. }
  785.  
  786. highlightGathering(){
  787. this.gatheringMap = {
  788. mines: "overviewGatheringBoxMines",
  789. fields: "overviewGatheringBoxFields",
  790. forest: "overviewGatheringBoxForest",
  791. fishing_pond: "overviewGatheringBoxFishingPond",
  792. kitchen: "overviewGatheringBoxKitchen",
  793. gem_mine: "overviewGatheringBoxGemMine",
  794. castle: "overviewGatheringBoxCastle",
  795. none: "none"
  796. }
  797.  
  798. const currentArea = IdlePixelPlus.getVarOrDefault("current_gathering_area", "none", "string")
  799. const areaId = this.gatheringMap[currentArea]
  800.  
  801. this.selectedGatheringArea = areaId
  802.  
  803. $(`#${areaId}`).addClass("overviewGatheringBoxSelected")
  804. }
  805.  
  806. changeGatheringArea(newArea){
  807. websocket.send("GATHERING=" + newArea);
  808. const newAreaId = this.gatheringMap[newArea]
  809.  
  810. const previousArea = this.selectedGatheringArea
  811. $(`#${previousArea}`).removeClass("overviewGatheringBoxSelected")
  812.  
  813. $(`#${newAreaId}`).addClass("overviewGatheringBoxSelected")
  814. this.selectedGatheringArea = newAreaId
  815. }
  816. }
  817.  
  818. const plugin = new OverviewPlugin();
  819. IdlePixelPlus.registerPlugin(plugin);
  820.  
  821. })();