melvor idle helper

have 5 features : auto loot, auto eat food, auto replant, auto sell junk and auto light bonfire.

  1. // ==UserScript==
  2. // @name melvor idle helper
  3. // @name:zh-TW melvor idle helper
  4. // @namespace https://melvoridle.com/
  5. // @version 0.2 (for melvor version:Alpha v0.17)
  6. // @description have 5 features : auto loot, auto eat food, auto replant, auto sell junk and auto light bonfire.
  7. // @description:zh-TW 共5種功能 : 自動掠奪、自動吃食物、自動種植、自動賣垃圾、自動燒柴。
  8. // @author cool9203
  9. // @match https://melvoridle.com/index.php
  10. // @include https://melvoridle.com/*
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. //---------show log setting---------
  15. let SHOW_LOG_STATUS = false;
  16. let MELVOR_VERSION = "Alpha v0.17";
  17.  
  18. //---------conditions setting---------
  19. let eat_food_size = 0.5;
  20. let sell_item_id = [];
  21. let junk_id = [648, 649, 650, 651, 652, 653, 654, 655];
  22. //let sell_item_id = [128, 129, 130, 131, 132, 669, 667, 670, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
  23.  
  24. //---------global variable(don't edit this area)---------
  25. let auto_loot = false;
  26. let auto_sell_junk = false;
  27. let auto_eat_food = false;
  28. let auto_light_bonfire = false;
  29. let auto_re_plant = false;
  30.  
  31.  
  32. //---------show message status variable---------
  33.  
  34.  
  35.  
  36. //---------features---------
  37.  
  38. function loot(){
  39. console.log("start loot");
  40. lootAll();
  41. }
  42.  
  43.  
  44. function sell_junk(){
  45. console.log("start sell_junk");
  46. for (let i = 0; i < junk_id.length; i++){
  47. let result = getBankId(junk_id[i]);
  48. if (result != false){
  49. sell_item(result);
  50. }
  51. }
  52.  
  53. for (let i = 0; i < sell_item_id.length; i++){
  54. let result = getBankId(sell_item_id[i]);
  55. if (result != false){
  56. sell_item(result);
  57. }
  58. }
  59. }
  60.  
  61.  
  62. function sell_item(index){
  63. let item_id = bank[index].id;
  64. console.log(`sell item: category=${items[item_id].category}, type=${items[item_id].type}, name=${items[item_id].name}`);
  65. selectBankItem(bank[index].id);
  66. sellQty = bank[index].qty;
  67. sellItem();
  68. document.querySelector(".swal2-confirm").click();
  69. }
  70.  
  71.  
  72. async function eat_food(){
  73. console.log("start eat_food");
  74. let max_hp = skillLevel[9] * 10;
  75. let now_hp = combatData["player"].hitpoints;
  76. let enemy_attack = parseInt( document.querySelector("#combat-enemy-strength-bonus").innerHTML.replace("(", "").replace(")", "").replace("-", "") );
  77.  
  78. if (SHOW_LOG_STATUS){
  79. console.log(`enemy_attack:${enemy_attack}`);
  80. }
  81.  
  82. if ((now_hp <= max_hp * eat_food_size) || (now_hp <= enemy_attack)){
  83. if (!equip_and_select_food()){ //if (not have any food) && ( (in combat) || (in thieving) )
  84. if (!isNaN(enemy_attack)){
  85. stopCombat(false, true, true);
  86. alert("you not have any food");
  87. }
  88. else if (npcID != null){
  89. pickpocket(npcID);
  90. alert("you not have any food");
  91. }
  92. return;
  93. }
  94.  
  95. while (true){
  96. let my_progress = parseInt( document.querySelector("#combat-progress-attack-player").style.width.replace("%", "") );
  97. let enemy_progress = parseInt( document.querySelector("#combat-progress-attack-enemy").style.width.replace("%", "") );
  98. enemy_attack = parseInt( document.querySelector("#combat-enemy-strength-bonus").innerHTML.replace("(", "").replace(")", "").replace("-", "") );
  99. if (isNaN(enemy_attack) || my_progress <= 10 || (now_hp <= enemy_attack) || (npcID != null && (now_hp <= max_hp * eat_food_size)) ){
  100. if (SHOW_LOG_STATUS){
  101. console.log(` my_progress:${my_progress}\n enemy_progress:${enemy_progress}\n now_hp:${now_hp}\n enemy_attack:${enemy_attack}\n`);
  102. }
  103. break;
  104. }else{
  105. await delay(50);
  106. }
  107. }
  108.  
  109. while (now_hp < max_hp * 0.98){
  110. eatFood();
  111. let eated_hp = combatData["player"].hitpoints;
  112. if (eated_hp == now_hp){
  113. if (eated_hp == max_hp || !equip_and_select_food()){
  114. break;
  115. }
  116. }else{
  117. if (SHOW_LOG_STATUS){
  118. console.log(`eat_food:${now_hp}->${eated_hp}`);
  119. }
  120. }
  121. now_hp = eated_hp;
  122. }
  123. }
  124. }
  125.  
  126.  
  127. function equip_and_select_food(){
  128. //get equippedFood count
  129. let equipped_food_count = 0;
  130. for (let i = 0; i < 3; i++){
  131. if (equippedFood[i].itemID != 0){
  132. equipped_food_count += 1;
  133. }
  134. }
  135.  
  136. //equip food
  137. for (let i = 0; i < bank.length; i++){
  138. if (equipped_food_count == 3){
  139. break;
  140. }
  141. let item_id = bank[i].id;
  142. if (items[item_id].canEat == true){ //if can eat
  143. selectBankItem(item_id);
  144. equipFoodQty = bank[i].qty;
  145. equipFood();
  146. equipped_food_count += 1;
  147. i -= 1;
  148. }
  149. }
  150.  
  151. //select food
  152. for (let i = 0; i < 3; i++){
  153. if (equippedFood[i].itemID != 0){
  154. selectEquippedFood(i);
  155. if (SHOW_LOG_STATUS){
  156. console.log("select food : equip and select food");
  157. }
  158. return true;
  159. }
  160. }
  161.  
  162. //if cann't select equip food, need quit combat ot thieving
  163. if (SHOW_LOG_STATUS){
  164. console.log("not have any food to equip and select");
  165. }
  166. return false;
  167. }
  168.  
  169.  
  170. function light_bonfire(){
  171. console.log("start light_bonfire");
  172. lightBonfire();
  173. }
  174.  
  175.  
  176. function add_gloop_or_compost(i, j){
  177. console.log("start add_gloop");
  178. if (i === undefined || j === undefined){
  179. for (let i = 0; i < newFarmingAreas.length; i++){
  180. for (let j = 0; j < newFarmingAreas[i].patches.length; j++){
  181. gloop_or_compost(i ,j);
  182. }
  183. }
  184. }else{
  185. gloop_or_compost(i ,j);
  186. }
  187. }
  188.  
  189.  
  190. function gloop_or_compost(i, j){
  191. if(checkBankForItem(CONSTANTS.item.Weird_Gloop)) {
  192. addGloop(i,j);
  193. } else {
  194. if(checkBankForItem(CONSTANTS.item.Compost)) {
  195. if(bank[getBankId(CONSTANTS.item.Compost)].qty < 5) {
  196. buyQty = 5 - bank[getBankId(CONSTANTS.item.Compost)].qty
  197. buyCompost(true)
  198. }
  199. } else {
  200. buyQty = 5
  201. buyCompost(true)
  202. }
  203. addCompost(i,j,5)
  204. }
  205. }
  206.  
  207.  
  208. function re_plant(){
  209. for (let i = 0; i < newFarmingAreas.length; i++){
  210. for (let j = 0; j < newFarmingAreas[i].patches.length; j++){
  211. let farm_patches = newFarmingAreas[i].patches[j];
  212. let last_seed = farm_patches.seedID;
  213. let grown_id = items[last_seed].grownItemID;
  214. if (farm_patches.hasGrown){ //if now is grown
  215. if(checkBankForItem(grown_id) || (bankMax + baseBankMax) > bank.length){ //check last_seed grown item in bank or bank is full
  216. harvestSeed(i,j);
  217. if (checkBankForItem(last_seed)){
  218. add_gloop_or_compost(i, j);
  219. }
  220. }
  221. selectedPatch = [i,j];
  222. selectedSeed = last_seed;
  223. plantSeed();
  224. }
  225. }
  226. }
  227. }
  228.  
  229. //---------option setting button---------
  230.  
  231. function create_helper_setting_button(){
  232. let main_item = document.createElement("li");
  233. let a = document.createElement("a");
  234. let span = document.createElement("span");
  235.  
  236. main_item.classList.add("nav-main-item");
  237. main_item.id = "helper_setting";
  238.  
  239. a.classList.add("nav-main-link");
  240. a.classList.add("nav-compact");
  241.  
  242. span.classList.add("nav-main-link-name");
  243. span.innerText = "helper setting";
  244.  
  245. main_item.insertAdjacentElement("beforeend", a);
  246. a.insertAdjacentElement("beforeend", span);
  247.  
  248. return main_item;
  249. }
  250.  
  251.  
  252. function create_helper_option(insert_obj, name, change_function, type, value){
  253. let option = document.createElement("input");
  254. option.classList.add("helper_option");
  255. option.type = type;
  256. option.value = value;
  257. option.style.display = "none";
  258. option.addEventListener("click", function(){
  259. change_function();
  260. });
  261.  
  262. let label = document.createElement("label");
  263. label.classList.add("helper_option");
  264. label.innerText = name;
  265. label.style.display = "none";
  266.  
  267. let next_line = document.createElement("br");
  268. next_line.classList.add("helper_option");
  269. next_line.style.display = "none";
  270.  
  271. insert_obj.insertAdjacentElement("afterend", option);
  272. option.insertAdjacentElement("afterend", label);
  273. label.insertAdjacentElement("afterend", next_line);
  274.  
  275. return next_line;
  276. }
  277.  
  278.  
  279. function helper_option_display(){
  280. let option_list = document.querySelectorAll(".helper_option");
  281.  
  282. for (let i = 0; i < option_list.length; i++){
  283. if (option_list[i].style.display.length == 0){
  284. option_list[i].style.display = "none";
  285. }else{
  286. option_list[i].style.display = "";
  287. }
  288. }
  289. }
  290.  
  291.  
  292. //---------main---------
  293. (async function() {
  294. console.log("tampermonkey start");
  295. console.log("melvor idle helper version:", MELVOR_VERSION)
  296.  
  297. //create helper button after setting_button and listen helper button.
  298. //listen action:show or hidden ".helper_option"
  299. let setting_button = document.querySelectorAll(".nav-main-item")[35];
  300. let helper_setting = create_helper_setting_button();
  301. setting_button.insertAdjacentElement("afterend", helper_setting);
  302. helper_setting.addEventListener("click", function(){
  303. helper_option_display();
  304. });
  305.  
  306. //create option and bind option listen function
  307. let next_obj = create_helper_option(helper_setting, "", sell_junk, "button", "sell junk");
  308. next_obj = create_helper_option(next_obj, "", add_gloop_or_compost, "button", "add all gloop");
  309. next_obj = create_helper_option(next_obj, "", equip_and_select_food, "button", "equip and select food");
  310. next_obj = create_helper_option(next_obj, "auto loot", change_auto_loot, "checkbox", "");
  311. next_obj = create_helper_option(next_obj, "auto sell junk", change_auto_sell_junk, "checkbox", "");
  312. next_obj = create_helper_option(next_obj, "auto eat food", change_auto_eat_food, "checkbox", "");
  313. next_obj = create_helper_option(next_obj, "auto light bonfire", change_auto_light_bonfire, "checkbox", "");
  314. next_obj = create_helper_option(next_obj, "auto replant", change_auto_re_plant, "checkbox", "");
  315. })();
  316.  
  317. function delay(ms){
  318. return new Promise((reslove, reject) => {
  319. setTimeout(() => {
  320. reslove("success");
  321. }, ms);
  322. });
  323. }
  324.  
  325.  
  326. //---------listen function---------
  327.  
  328. function change_auto_loot(){
  329. if (auto_loot == false){
  330. loot();
  331. auto_loot = setInterval(loot, 10000);
  332. }else{
  333. clearInterval(auto_loot);
  334. auto_loot = false;
  335. }
  336. }
  337.  
  338. function change_auto_sell_junk(){
  339. if (auto_sell_junk == false){
  340. sell_junk();
  341. auto_sell_junk = setInterval(sell_junk, 10000);
  342. }else{
  343. clearInterval(auto_sell_junk);
  344. auto_sell_junk = false;
  345. }
  346. }
  347.  
  348. function change_auto_eat_food(){
  349. if (auto_eat_food == false){
  350. eat_food();
  351. auto_eat_food = setInterval(eat_food, 200);
  352. }else{
  353. clearInterval(auto_eat_food);
  354. auto_eat_food = false;
  355. }
  356. }
  357.  
  358. function change_auto_light_bonfire(){
  359. if (auto_light_bonfire == false){
  360. light_bonfire();
  361. auto_light_bonfire = setInterval(light_bonfire, 20500);
  362. }else{
  363. clearInterval(auto_light_bonfire);
  364. auto_light_bonfire = false;
  365. }
  366. }
  367.  
  368. function change_auto_re_plant(){
  369. if (auto_re_plant == false){
  370. re_plant();
  371. auto_re_plant = setInterval(re_plant, 301000);
  372. }else{
  373. clearInterval(auto_re_plant);
  374. auto_re_plant = false;
  375. }
  376. }