Guest User

mazmorra.io hotkeys + bot scripts v4.5_20_07_2019

a guest
Jul 20th, 2019
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /** Tampermonkey script **/
  2.  
  3. // ==UserScript==
  4. // @name         Mazmorra Script
  5. // @namespace    mazmorra
  6. // @version      1.4.5
  7. // @description  Hotkeys and hacks for mazmorra.io!
  8. // @author       goblin
  9. // @match        https://mazmorra.io/
  10. // @grant        unsafeWindow
  11. // ==/UserScript==
  12.  
  13. // PARAMETERS' : (Modify to fit your needs and your character stats!)
  14.  
  15. // INIT:
  16. var HELLO = "Mazmorra script ready! Version compatibile with: \n\n '(19/07/2019), Settings update, skill balancing, bug fixes.'";
  17. var USERNAME = "goblin";
  18. // script SETUP:
  19. var HP_WOUND = 160; // configuration for S hotkey - will not quick-drink hp-potion if hp missing is less than HP_WOUND
  20. var MP_WOUND = 80; // configuration for S hotkey - will not quick-drink mp-potion if mp missing is less than MP_WOUND
  21. var HP_CRITICAL = 400; // (if = 0 or >= maxhp, then HP_WOUND is considered, else:) if hp <= HP_CRITICAL, "Health Keeper" (if can't drink hp-potion) will try to portal-escape to spawn
  22. var INVENTORY_KEEP = 4; // prevents 'oldest'/top-left set amount of items from being quick-sold with A while at spawn (set to 15 to disable quick-sell / set to 0 to allow to sell everything)
  23. var KEEP_STACKABLES = false; // if true, hotkey scripts ignore at least one instance of stackables. (which means if you have exactly 1 portal/potion, then you don't have it.)
  24. // bot SETUP:
  25. var INTERVAL = 90; // refresh interval for auto-scripts in ms (Example: "Health Keeper")
  26. var PORTAL_ESCAPE_FAIL = 4; // if "Health Keeper" fails to escape via portal this many times (surrounded by enemies?), then it starts running to previous floor (while retrying) - fixes unable to portal while surrounded by enemies
  27. var CHECKPOINT_WALK_DELAY = 800; // delay to prevent double-enter-bug on checkpoints
  28. // bot MODES:
  29. var NO_LOOT = false; // if true, "Dungeon Clear" will not pickup loot, only kill enemies for xp
  30. var ASCEND_MODE = true; // if true, "Autoloop X" will ascend (until last floor) instead of returning to spawn directly, after the floor is "clean"
  31. var AVOID_PLAYERS = true; // if true, "Autoloop X" will temporarily go farm to previous checkpoint if it encounters a player blocking its farm floor X, instead of retreating to spawn
  32. var PREFEER_SPAWN = true; // if true, any CHECKPOINT request to 120 will be redirected to 1 instead.
  33. var ALLOWED_MANA_GAP = 50; // allowed mana gap for "Dungeon Clear" level fountain function (to prevent getting stuck on fountain if skill spam is triggered)
  34. var STATIONARY_HP_TIMEOUT = 6000; // used to avoid "Dungeon Clear" getting trapped by the monkey minion BUG
  35. // Script functions help' : (some keys have multiple functions depending on location)
  36. /**
  37.  
  38.     HOTKEYS:
  39.  
  40.     (if player is NOT AT SPAWN)
  41.     Key:    Action:
  42.      A       - auto-attack nearest enemy (built-in-game)
  43.      S       - quick-restore (drink hp potion if HP_WOUND or more hp missing && drink mp potion if MP_WOUND or more mana missing)
  44.      D       - cast a portal (if not avaliable in room) / walk into portal (if avaliable in room)
  45.  
  46.      F       - fountain: clicks on fountain tile (if avaliable and reachable)
  47.      E       - explore: clicks on door_to_next_floor tile (if reachable - can be blocked by lever gates?)
  48.      R       - return: clicks on door_to_previous_floor tile (always reachable?)
  49.      C       - checkpoint: clicks on check-point tile (always reachable?)
  50.      L       - lever: clicks on lever-tile (tip: sometimes E won't budge since lever-gates can block door_to_next_floor)
  51.  
  52.     (if player is AT SPAWN - * indicates a new function - ! indicates bugs)
  53.      Key:   Action:
  54.      A       * walk to Merchant (if shop not open) / quick-sell an item right after INVENTORY_KEEP amount of items (if shop open)
  55.      S       * walk to Elder (if shop not open) / buy hp potion from Elder (if shop open)
  56.      D       * walk to portal (if avaliable in room) / buy scroll_regular from Elder (if shop open)
  57.  
  58.      F       - fountain: clicks on fountain tile (if avaliable and reachable)
  59.      E       - explore: clicks on door_to_next_floor tile (if reachable - can be blocked by lever gates?)
  60.      R       - return: clicks on door_to_pvp (door_to_previous_floor tile at spawn)
  61.      C       - checkpoint: clicks on check-point tile (always reachable?)
  62.      L       *! leaderboard: clicks on leaderboard tile (WARNN: bug: You must manually click away to close it or it gets broke D:)
  63.      M       * Majesty: clicks on majesty tile / refreshes majesty
  64.  
  65.  
  66.     SCRIPTS:
  67.  
  68.     (Numpad keys && NumLock = ON)
  69.     Key:    Action:
  70.      7       - toggle "Health Keeper":  + if HP_WOUND hp missing, it will try drink hp-potion. Else, if no potion: (TIP: Always have a scroll)
  71.                                         + if hp is <= HP_CRITICAL (or HP_CRITICAL invalid), it will try reach checkpoint OR (if not avaliable) auto_portal escape to spawn
  72.                                         + if no checkpoint and can't portal escape to spawn (surrounded by enemies?) it will try to flee to previous floor first, then retry
  73.                                         + if at spawn and hp != max_hp (or mp), it'll go force drink from fountain
  74.                                         + if at spawn, and has no portals in inventory, it'll go try forcefully buy a scroll
  75.  
  76.      8       - toggle "Dungeon Clear"   + if loot avaliable, it will run to pick it up first (doesn't open chests)
  77.                                         + if no loot dropped, it will auto attack a random enemy on the floor
  78.                                         + if no enemies left, it'll drink from a level fountain if avaliable, AND IF UNDER ALLOWED_MANA_GAP
  79.                                         + if at spawn, it will autosell inventory (modify INVENTORY_KEEP)
  80.  
  81.      9       - toggle "Autoloop X"      ? RECOMMENDED: "Dungeon Clear" mode alongside it, so they together farm the checkpoint X floor (Or from X to 120 if ASCEND_MODE is active)
  82.                                         + if in ASCEND_MODE, it fill first go trigger (one-player) levers (to unblock possibly blocked doors)
  83.                                         + if no loot or enemies at the current floor, it will (auto-flee to spawn) OR (ascend to next floor)
  84.                                         + if nothing to do at spawn, it will autowalk back to checkpoint X
  85.  
  86.      4       - toggle "Skill-1 Spam"    + Spam Q key to activate attack speed skill (if not at spawn)
  87.  
  88.      5       - toggle "Skill-2 Spam"    + Spam W key to activate movement speed skill (if not at spawn)
  89. **/
  90.  
  91.  
  92.  
  93. // DOCUMENTATION' :
  94.  
  95. if ("name" === "Helper functions") {
  96.     myplayer.name;                                  // get USERNAME from PARAMETERS'
  97.     myplayer.data();                                // get user data from in-game myplayer object
  98.     myplayer.inventory();                           // get inventory slots in raw form
  99.     room.entities('type', 'kind', 'only_first');    // get entities of type,kind (returns all if type is not speficied) from current room
  100.     room.shop();                                    // get shop slots from current room/stage/floor if avaliable
  101.     room.floor();                                   // get room (floor) number
  102. }
  103. if ("name" === "Control functions") {
  104.     controller.inventory_find('type');              // finds first item from inventory of whose type string starts with 'type'
  105.     controller.inventory_consume('slot_id')         // consumes item from inventory from slot slot_id
  106.     controller.shop_buy('type');                    // buy item from shop of whose type string starts with 'type' (if shop avaliable - returns false if not found)
  107.     controller.shop_sell('slot_id');                // sell item to shop from slot_id of inventory - returns false if shop not enabled
  108.     controller.myplayer_click('x','y');             // clicks on x,y position tile (moves/attacks/collects loot/...)
  109.     controller.myplayer_click_on('type','kind');    // clicks on random (first returned by room.entities) entity of type,kind - return true if found
  110.     controller.checkpoint_click('floor');           // click CP (enter valid floor number pls, ty.)
  111. }
  112. if ("name" == "Action functions") {
  113.     action.auto_attack();                           // auto-attack nearest enemy (use 'false' if binded again to A key)
  114.     action.hp_potion(80);                           // drinks a hp potion if it will fully use the fattest one (80 hp currently) (returns false if item not found)
  115.     action.mp_potion(1);                            // consumes a mp potion if there's at least 1 missing mana (returns false if item not found)
  116.     action.scroll_regular();                        // (re)cast a portal in the room (returns false if item not found)
  117. }
  118. if ("name" == "Debug functions") {
  119.     room.entities('', '', '', '', true);            // DEBUG: logs entities: x, y, type, kind, e*
  120.     controller.inventory_find('',true);             // DEBUG: logs item types from inventory in console
  121. }
  122. if ("name" == "Document worker") {
  123.     document_worker.set_info_text('string');        // replaces "discord" div text with 'string'
  124.     document_worker.update_info_text();             // replaces "discord" div text with active scripts info
  125.     document_worker.loop_start(INTERVAL);           // starts scripts loop interval function (at INTERVAL refresh rate)
  126.     document_worker.loop_stop();                    // stops scripts loop interval function
  127.     document_worker.are_scripts_running();          // returns true if at least one loop-script is running
  128.     loop_function();                                // exectues one iteration of loop function
  129. }
  130.  
  131.  
  132.  
  133. // DEFINE SCRIPT KEY BINDINGS' :
  134.  
  135. // helper function for writting bindings
  136. function key_code(KEY_CHAR) {return KEY_CHAR.toUpperCase().charCodeAt(0);};
  137.  
  138. // key bindings
  139. document.addEventListener('keydown', function(event){
  140.     let key = event.keyCode;
  141.  
  142.     // hotkeys script is disabled?
  143.     if (document_worker.state_activity[0] === false) return;
  144.  
  145.     if (key == key_code("A")) {
  146.         if (room.floor() == 1 || room.floor() == 120) {
  147.             // if shop not enabled
  148.             if(controller.shop_sell(INVENTORY_KEEP) === false) {
  149.                 // NPCs are type "20", and Merchant is "merchant" kind
  150.                 controller.myplayer_click_on("20","merchant");
  151.             }
  152.         } else {
  153.             action.auto_attack(false);
  154.         }
  155.     } else
  156.     if (key == key_code("S")) {
  157.         if (room.floor() == 1 || room.floor() == 120) {
  158.             // if didn't found hp_potion to buy
  159.             if (controller.shop_buy("hp-potion") === false) {
  160.                 // NPCs are type "20", and Elder is "elder" kind
  161.                 controller.myplayer_click_on("20","elder");
  162.             }
  163.         } else {
  164.             action.hp_potion(HP_WOUND);
  165.             action.mp_potion(MP_WOUND);
  166.         }
  167.     } else
  168.     if (key == key_code("D")) {
  169.         if ((room.floor() == 1 || room.floor() == 120) && (controller.shop_buy("scroll-regular") === true)) {
  170.             //
  171.         } else {
  172.             let portal = room.entities("portal",undefined,true);
  173.             if (portal.length === 0) {
  174.                 action.scroll_regular();
  175.             } else {
  176.                 controller.myplayer_click(portal[0].position.x, portal[0].position.y);
  177.             }
  178.         }
  179.     } else
  180.     if (key == key_code("F")) {
  181.         controller.myplayer_click_on("fountain");
  182.     } else
  183.     if (key == key_code("E")) {
  184.         if (room.floor() == 1) {
  185.             // doors forward are of type 0 and kind 2 at spawn
  186.             controller.myplayer_click_on("0",2);
  187.         } else {
  188.             // doors forward are of type 0 and kind -2
  189.             controller.myplayer_click_on("0",-2);
  190.         }
  191.     } else
  192.     if (key == key_code("R")) {
  193.         if (room.floor() == 1) {
  194.             // doors to pvp are of type 0 and kind 'pvp'
  195.             controller.myplayer_click_on("0","pvp");
  196.         } else {
  197.             // doors backwards are of type 0 and kind -1
  198.             controller.myplayer_click_on("0",-1);
  199.         }
  200.     } else
  201.     if (key == key_code("C")) {
  202.         controller.myplayer_click_on("check-point");
  203.     } else
  204.     if (key == key_code("L")) {
  205.         if (room.floor() == 1 || room.floor() == 120) {
  206.             controller.myplayer_click_on("leaderboard");
  207.         } else {
  208.             controller.myplayer_click_on("lever");
  209.         }
  210.     } else
  211.     if (key == key_code("M")) {
  212.         if (room.floor() == 1 || room.floor() == 120) {
  213.             // NPCs are type "20", and Majesty is "majesty" kind
  214.             controller.myplayer_click_on("20","majesty");
  215.         } else {
  216.             //
  217.         }
  218.     } else if (key === 103) { // numpad 7 key - toggle "Health Keeper"
  219.         document_worker.toggle_script(1);
  220.     } else if (key === 104) { // numpad 8 key - toggle "Dungeon Clear"
  221.         document_worker.toggle_script(2);
  222.     } else if (key === 105) { // numpad 9 key - toggle "Autoloop X "
  223.         if (document_worker.state_activity[3] === false) {
  224.             let target_floor = prompt('Enter floor (valid checkpoint) number:');
  225.             document_worker.autowalk_target = target_floor;
  226.         } else {
  227.             document_worker.autowalk_target = 1;
  228.         }
  229.         document_worker.toggle_script(3);
  230.     } else if (key === 100) { // numpad 4 key - toggle "Skill-1 Spam"
  231.         document_worker.toggle_script(4);
  232.     } else if (key === 101) { // numpad 5 key - toggle "Skill-2 Spam"
  233.         document_worker.toggle_script(5);
  234.     }
  235. });
  236.  
  237.  
  238.  
  239. // DEFINE SCRIPT OBJECTS' :
  240.  
  241. //* action object */
  242. function Action() {};
  243. //
  244. // auto-attack nearest enemy
  245. Action.prototype.auto_attack = function(repeat = true) {
  246.     // AUTO ATTACK IS BUILT IN GAME: (no need to call it twice if binded to A key)
  247.     if (repeat === true) {
  248.         window.factory.level.room.send(['atk']);
  249.     }
  250. }
  251. //
  252. // consumes a hp potion if there's at least hp_missing missing health (returns false if item not found)
  253. Action.prototype.hp_potion = function(hp_missing = 1) {
  254.     if (myplayer.data().hp.max - myplayer.data().hp.current >= hp_missing) {
  255.         let slot = controller.inventory_find("hp-potion");
  256.         if (slot[0] === undefined) return false;
  257.         controller.inventory_consume(slot[0]);
  258.         return true;
  259.     }
  260.     return undefined;
  261. }
  262. //
  263. // consumes a mp potion if there's at least mp_missing missing mana (returns false if item not found)
  264. Action.prototype.mp_potion = function(mp_missing = 1) {
  265.     if (myplayer.data().mp.max - myplayer.data().mp.current >= mp_missing) {
  266.         let slot = controller.inventory_find("mp-potion");
  267.         if (slot[0] === undefined) return false;
  268.         controller.inventory_consume(slot[0]);
  269.         return true;
  270.     }
  271.     return undefined;
  272. }
  273. //
  274. // (re)cast a portal in the room
  275. Action.prototype.scroll_regular = function() {
  276.     let slot = controller.inventory_find("scroll-regular");
  277.     if (slot[0] === undefined) return false;
  278.     controller.inventory_consume(slot[0]);
  279.     return true;
  280. }
  281.  
  282. //* myplayer object */
  283. function Player(name) {this.name = name;};
  284. //
  285. // get user data from in-game myplayer object
  286. Player.prototype.data = function() {
  287.     return window.hud.controller.playerObject.userData;
  288. };
  289. //
  290. // get inventory slots either form main or quick inventory
  291. Player.prototype.inventory = function(quick = false) {
  292.     return window.hud.inventory.slots.slots;
  293. };
  294.  
  295. //* room object */
  296. function Room() {};
  297. //
  298. // get entities of type,kind (returns all if type is not speficied) from current room
  299. Room.prototype.entities = function(type = undefined, kind = undefined, only_first = false, alive = false, debug = false, exact = false) {
  300.     if (type === '') type = undefined;
  301.     if (kind === '') kind = undefined;
  302.     if (only_first === '') only_first = false;
  303.     if (alive === '') alive = false;
  304.     let all_entities = window.factory.level.entities;
  305.     let my_entities = [];
  306.     let count = 0;
  307.     for (let id in all_entities) {
  308.         let e = all_entities[id].userData;
  309.         if (
  310.             (type === undefined || (exact === false && e.type.substring(0,type.length) === type) || (exact === true && e.type === type)) &&
  311.             ((type === "lever" && kind === e.active) || (type === "fountain" && kind === e.active) || kind === undefined || e.kind === kind || (e._destiny !== undefined && (e._destiny.progress === kind || e._destiny._room === kind)))
  312.             ) {
  313.             if (alive === false || (e.hp !== undefined && e.hp.current > 0)) {
  314.                 my_entities[count] = e;
  315.                 count = count + 1;
  316.                 if (debug === true) {
  317.                     console.log(e.position.y,e.position.x,e.type,e.kind,e);
  318.                 }
  319.                 if (only_first === true) return my_entities;
  320.             }
  321.         }
  322.     }
  323.     return my_entities;
  324. }
  325. //
  326. // get shop slots from current room/stage/floor if avaliable
  327. Room.prototype.shop = function() {
  328.     return window.hud.inventory.purchaseSlots;
  329. }
  330. //
  331. // get floor number
  332. Room.prototype.floor = function() {
  333.     if (window.factory === undefined || window.factory.level === undefined || window.factory.level.room === undefined || window.factory.level.room.state === undefined)
  334.         return 0;
  335.     let floor = window.factory.level.room.state.progress;
  336.     if (floor === undefined) {
  337.         if (window.factory.level.room.options === undefined || window.factory.level.room.options.progress === undefined)
  338.             return 0;
  339.         else
  340.             return window.factory.level.room.options.progress;
  341.     }
  342.     else {
  343.         return floor;
  344.     }
  345. }
  346.  
  347. //* controller object */
  348. function Controller() {};
  349. // consume item from inventory of whose type string starts with 'type'
  350. // DEBUG: if second parameter is 'true', it'll log item types from inventory in console
  351. Controller.prototype.inventory_find = function(type, debug = false) {
  352.     let i, item_id;
  353.     let found_item = false;
  354.     // search for item in inventory
  355.     let inventory = myplayer.inventory();
  356.     for (i = 0; i < 15; i++) {
  357.         let item_type = inventory[i].item;
  358.         if (item_type != null) {
  359.             // will ignore kept stackable items
  360.             if (controller.is_kept(inventory[i]) === false) {
  361.                 if (type == item_type.userData.item.type.substring(0,type.length)) {
  362.                     item_id = i;
  363.                     found_item = true;
  364.                     if (debug === false) break;
  365.                 }
  366.                 if (debug === true) console.log(i, item_type.userData.item.type);
  367.             } else {
  368.                 // pass
  369.             }
  370.         }
  371.     }
  372.     if (found_item && debug === false) {
  373.         return [item_id, false];
  374.     }
  375.     else {
  376.         // quickInventory was removed from the game.
  377.     }
  378.     return [undefined,undefined];
  379. }
  380. //
  381. // check if allowed to consume
  382. Controller.prototype.is_kept = function(slot) {
  383.     if (KEEP_STACKABLES === true
  384.         && slot.item !== undefined
  385.         && slot.item.userData !== undefined
  386.         && slot.item.userData.item !== undefined) {
  387.  
  388.             let qty = slot.item.userData.item.qty;
  389.             if (qty === 1) return true;
  390.             else return false;
  391.     } else {
  392.         return false;
  393.     }
  394.     return true;
  395. }
  396. //
  397. // consumes item from inventory from slot slot_id
  398. Controller.prototype.inventory_consume = function(slot_id) {
  399.     let inventory = myplayer.inventory(false);
  400.     // will not consume if it is a kept stackable / or room not loaded
  401.     if (controller.is_kept(inventory[slot_id]) === true || window.factory === undefined || window.factory.level === undefined ||window.factory.level.room === undefined) {
  402.         return;
  403.     }
  404.     window.factory.level.room.send(["use-item", {
  405.         inventoryType: "inventory",
  406.         itemId: inventory[slot_id].item.userData.itemId
  407.     }]);
  408. }
  409. //
  410. // buy item from shop of whose type string starts with 'type' (if shop avaliable - returns false if not found)
  411. Controller.prototype.shop_buy = function(type) {
  412.     if (type === '' || type == undefined || type == null) return false;
  413.     if (room.shop().enabled === false) return false;
  414.     for (let id in room.shop().userData.slots) {
  415.         if (type === room.shop().userData.slots[id].type.substring(0,type.length)) {
  416.             window.factory.level.room.send(["use-item", {
  417.                 inventoryType: "purchase",
  418.                 itemId: room.shop().userData.slots[id].id
  419.             }]);
  420.             // returns true if item found
  421.             return true;
  422.         }
  423.     }
  424.     return false;
  425. }
  426. //
  427. // sell item to shop from slot_id of inventory - returns false if shop not enabled
  428. Controller.prototype.shop_sell = function(slot_id = 0) {
  429.     if (room.shop().enabled === false) return false;
  430.     let slot = myplayer.inventory()[slot_id];
  431.     if (slot === null || slot === undefined) {
  432.         return false;
  433.     }
  434.     if (slot.item === null || slot.item === undefined) {
  435.         return false;
  436.     }
  437.     slot.dispatchSell({
  438.         fromInventoryType: slot.parent.inventoryType,
  439.         itemId: slot.item.userData.itemId
  440.     });
  441.     return true;
  442. }
  443. //
  444. // clicks on x,y position tile (moves/attacks/collects loot/...)
  445. Controller.prototype.myplayer_click = function(x, y) {
  446.     // closes inventory overlay to unblock view
  447.     if (window.hud.inventory.isOpen) window.hud.onToggleInventory();
  448.     // closes checkpoint overlay to unblock view
  449.     if (window.hud.checkPointSelector.isOpen) window.hud.checkPointSelector.parent.forceCloseOverlay();
  450.     // sends click data to server (inverted because it works like that in game client)
  451.     document_worker.last_click = [y,x]; // remember last clik (invert?)
  452.     let moveCommand = {
  453.         x: y,
  454.         y: x,
  455.     };
  456.     window.factory.level.room.send(['move', moveCommand]);
  457. }
  458. //
  459. // clicks on random (first returned by room.entities) entity of type,kind - return true if found
  460. Controller.prototype.myplayer_click_on = function(type, kind, alive = false) {
  461.     let target = room.entities(type, kind, true, alive)[0];
  462.     if (target === undefined || target == null) return false;
  463.     if (target.position === undefined || target.position == null) return false;
  464.     if (alive === true && target.hp.current <= 0) return false;
  465.     if (alive === true && target.hp !== undefined) { // used for enemy can't-get-attacked-bug workaround
  466.         document_worker.last_enemy_hp_observed = target.hp.current;
  467.     }
  468.     controller.myplayer_click(target.position.x, target.position.y);
  469.     return true;
  470. }
  471. //
  472. // click CP
  473. Controller.prototype.checkpoint_click = function(floor) {
  474.     if (window.hud.checkPointSelector.isOpen) window.hud.checkPointSelector.parent.forceCloseOverlay();
  475.     window.hud.checkPointSelector.dispatchEvent(
  476.         {
  477.             type:
  478.             "checkpoint",
  479.             bubbles:!0,
  480.             progress:floor
  481.         }
  482.     );
  483. }
  484.  
  485.  
  486.  
  487. // DOCUMENT MANIPULATION' :
  488.  
  489. //* Bot/Automation object */
  490. function Document_worker() {
  491.     this.state_activity = [true, false, false, false, false, false];
  492.     this.state_info = ["Hotkey Script","Health Keeper","Dungeon Clear","Autoloop","Skill-1 Spam","Skill-2 Spam"];
  493.     this.loop = 0;
  494.     this.isLoopRunning = false;
  495.     this.measure_time = Date.now();
  496.     this.busy = false;
  497.     this.portal_escape_attempts = 0;
  498.     this.shop_action_delay = 0;
  499.     this.measure = 0;
  500.     this.autowalk_target = 0;
  501.     this.checkpoint_delay = 0;
  502.     this.last_click = [0,0];
  503.     this.last_enemy_hp_observed = 0;
  504.     this.stationary_hp_timer = 0;
  505. };
  506. //
  507. // replaces "discord" div text with 'string'
  508. Document_worker.prototype.set_info_text = function(string) {
  509.     let feedback_div = document.getElementsByClassName("feedback")[0];
  510.     feedback_div.innerText = string;
  511. }
  512. //
  513. // replaces "discord" div text with active scripts info
  514. Document_worker.prototype.update_info_text = function() {
  515.     let feedback_div = document.getElementsByClassName("feedback")[0];
  516.     feedback_div.innerText = "";
  517.     for (let i in this.state_activity) {
  518.         if (this.state_activity[i] === true) {
  519.             if (feedback_div.innerText !== "")
  520.                 feedback_div.innerText += "\n";
  521.             feedback_div.innerText += this.state_info[i];
  522.             if (i==3)
  523.                 feedback_div.innerText += (" " + this.autowalk_target);
  524.         }
  525.     }
  526. }
  527. //
  528. // start scripts loop interval function
  529. Document_worker.prototype.loop_start = function(delay) {
  530.     this.isLoopRunning = true;
  531.     this.loop = window.setInterval(loop_function, delay);
  532. }
  533. //
  534. // stops scripts loop interval function
  535. Document_worker.prototype.loop_stop = function() {
  536.     this.isLoopRunning = false;
  537.     window.clearInterval(this.loop);
  538. }
  539. //
  540. // returns true if at least one loop-script is running
  541. Document_worker.prototype.are_scripts_running = function() {
  542.     let running = false;
  543.     for (let i=1; i<this.state_activity.length; i += 1) {
  544.         if (this.state_activity[i] === true) {
  545.             return true;
  546.         }
  547.     }
  548.     return false;
  549. }
  550. //
  551. // toggle script for given script_id
  552. Document_worker.prototype.toggle_script = function(script_id = 0) {
  553.     if (script_id === 0) return undefined;
  554.     if (document_worker.state_activity[script_id] === false) {
  555.         document_worker.state_activity[script_id] = true;
  556.         if (document_worker.isLoopRunning === false) {
  557.             document_worker.loop_start(INTERVAL);
  558.         }
  559.     } else {
  560.         document_worker.state_activity[script_id] = false;
  561.         if (document_worker.are_scripts_running() === false && document_worker.isLoopRunning === true) {
  562.             document_worker.loop_stop();
  563.         }
  564.     }
  565.     this.update_info_text();
  566. }
  567. //
  568. //
  569. // loop function
  570. function loop_function() {
  571.     if (room === undefined || room.floor() === 0 || window.factory === undefined || window.factory.level === undefined || window.factory.level.room === undefined) return;
  572.  
  573.     document_worker.measure = Date.now();
  574.     if (document_worker.busy === false && document_worker.state_activity[1] === true) { // "Health Keeper" is active
  575.         if (room.floor() === 1 || room.floor() === 120) { // at spawn
  576.             // forcefully drink from fountain
  577.             if (myplayer.data().hp.current < myplayer.data().hp.max || myplayer.data().mp.current < myplayer.data().mp.max) { // hp is not restored
  578.                 controller.myplayer_click_on("fountain");
  579.                 document_worker.busy = true; // won't click on other things if busy healing up
  580.             }
  581.             if (document_worker.shop_action_delay === 0) {
  582.                 // forcefully restock on portals
  583.                 let slot = controller.inventory_find("scroll-regular");
  584.                 if (slot[0] === undefined) {
  585.                     document_worker.busy = true; // won't click on other things if having to buy portals
  586.                     document_worker.shop_action_delay = Date.now();
  587.                     // if didn't found hp_potion to buy
  588.                     if (controller.shop_buy("scroll-regular") === false) {
  589.                         // NPCs are type "20", and Elder is "elder" kind
  590.                         controller.myplayer_click_on("20","elder");
  591.                     }
  592.                 }
  593.             // shop action delay needed to not overbuy on items
  594.             } else {
  595.                 if (document_worker.measure - document_worker.shop_action_delay > 200) {
  596.                     document_worker.shop_action_delay = 0;
  597.                     document_worker.busy = true; // won't click on other things if having to buy portals
  598.                 }
  599.             }
  600.             if (document_worker.portal_escape_attempts > 0) {
  601.                 document_worker.portal_escape_attempts = 0;
  602.             }
  603.         }
  604.         else {
  605.             if (action.hp_potion(HP_WOUND) === false) {
  606.                 // can't drink hp potion?
  607.                 // if hp is critical?
  608.                 if (((HP_CRITICAL === 0 || HP_CRITICAL >= myplayer.data().hp.max) && (myplayer.data().hp.max-myplayer.data().hp.current) >= HP_WOUND) || myplayer.data().hp.current <= HP_CRITICAL) {
  609.                     document_worker.FLEE_PROCEDURE();
  610.                     document_worker.busy = true; // won't click on other things if busy healing up
  611.                 }
  612.             }
  613.         }
  614.     }
  615.     if (document_worker.busy === false && document_worker.state_activity[3] === true && ASCEND_MODE === true) { // "Autoloop X" is active - ASCEND_MODE
  616.         //+ if in ASCEND_MODE, it fill first go trigger (one-player) levers (to unblock possibly blocked doors)
  617.         if (room.floor()%2===0 && controller.myplayer_click_on("lever", false) === true) { // PROTIP: NON-LOOT LEVERS SPAWN ONLY ON EVEN FLOORS?
  618.             document_worker.busy = true; // won't go into below actions if there's a non-triggered lever
  619.         }
  620.     }
  621.     if (document_worker.busy === false && document_worker.state_activity[2] === true) { // "Dungeon Clear" is active
  622.         if (room.floor() === 1 || room.floor() === 120) { // at spawn
  623.             // has things to sell
  624.             if (myplayer.inventory()[INVENTORY_KEEP].item !== null) {
  625.                 // if shop not enabled
  626.                 if(controller.shop_sell(INVENTORY_KEEP) === false) {
  627.                     // NPCs are type "20", and Elder is "elder" kind
  628.                     controller.myplayer_click_on("20","elder");
  629.                 }
  630.                 document_worker.busy = true; // won't click on other things if selling stuff
  631.             }
  632.         } else {
  633.             // will run to pickup dropped loot (does not open avliable chests)
  634.             let looting = true;
  635.             if (NO_LOOT === false) { // if inv. not full
  636.             if (controller.myplayer_click_on('diamond') === false)
  637.                 if (controller.myplayer_click_on('gold') === false)
  638.                     if (myplayer.inventory()[14].item === null) { // + no room in inv, will not get stuck looting :D
  639.                         if (controller.myplayer_click_on('armor') === false)
  640.                             if (controller.myplayer_click_on('shield') === false)
  641.                                 if (controller.myplayer_click_on('helmet') === false)
  642.                                     if (controller.myplayer_click_on('boots') === false)
  643.                                         if (controller.myplayer_click_on('weapon') === false)
  644.                                             if (controller.myplayer_click_on('bow') === false)
  645.                                                 if (controller.myplayer_click_on('wand') === false)
  646.                                                     if (controller.myplayer_click_on('xp-potion') === false)
  647.                                                         looting = false;
  648.                     } else {
  649.                         looting = false;
  650.                     }
  651.             } else {
  652.                 looting = false;
  653.             }
  654.             if (looting === false) {
  655.                 // 1000 is an enemy type, it also must be alive
  656.                 let get_last_hp = document_worker.last_enemy_hp_observed;
  657.                 if ((STATIONARY_HP_TIMEOUT===0 || document_worker.stationary_hp_timer < STATIONARY_HP_TIMEOUT/INTERVAL) && controller.myplayer_click_on('1000',undefined,true) === true) {
  658.                     action.auto_attack(true);
  659.                     document_worker.busy = true; // won't click on other things if fighting ("Health Keeper" > "Dungeon Clear" priority, still)
  660.                     // BUG FIX (MONKEYS CAN TRAP PLAYER AND BE IMMORTAL SO YOU DIE SLOWLY... UNLESS:)
  661.                     if (get_last_hp == document_worker.last_enemy_hp_observed) {
  662.                         document_worker.stationary_hp_timer += 1;
  663.                     } else {
  664.                         document_worker.stationary_hp_timer = 1;
  665.                     }
  666.                 } else {
  667.                     document_worker.stationary_hp_timer = 0;
  668.                     // chill (nothing to do... go to spawn? OR Alternative idea: make it ascend the floor? - tip: then you need to handle levers and blockages.)
  669.                     //document_worker.FLEE_PROCEDURE();
  670.                     if (controller.myplayer_click_on("fountain") === true && (myplayer.data().hp.current<myplayer.data().hp.max || myplayer.data().mp.current+ALLOWED_MANA_GAP<myplayer.data().mp.current)) {
  671.                         // spam the fukin fountain to healup m8
  672.                     } else
  673.                     if (document_worker.state_activity[3] === true) {
  674.                         document_worker.RESET_FARM();
  675.                     }
  676.                 }
  677.             }
  678.         }
  679.     }
  680.     if (document_worker.busy === false && document_worker.state_activity[3] === true) { // "Autoloop X" is active
  681.         if (room.floor() === 1 || room.floor() === 120) { // at spawn
  682.             //if (document_worker.measure - document_worker.checkpoint_delay > CHECKPOINT_WALK_DELAY) {
  683.                 if (Document_worker.prototype.CHECKPOINT(document_worker.autowalk_target) === true) {
  684.                     // fleeing to checkpoint.
  685.                     document_worker.busy = true; // won't click on other things if busy walking towards check-point
  686.                     //document_worker.checkpoint_delay = document_worker.measure;
  687.                 }
  688.             //}
  689.         } else if (document_worker.state_activity[3] === false) {
  690.             document_worker.RESET_FARM();
  691.         }
  692.     }
  693.     if (/*document_worker.busy === false &&*/ document_worker.state_activity[4] === true) { // "Skill-1 Spam" is active
  694.         if (room.floor() === 1 || room.floor() === 120) { // at spawn
  695.             // dont spam skills at spawn lol
  696.         } else if (myplayer.data().mp.current >= 15) {
  697.             hud.skill1Button._listeners.click[0]();
  698.         }
  699.     }
  700.     if (/*document_worker.busy === false &&*/ document_worker.state_activity[5] === true) { // "Skill-2 Spam" is active
  701.         if (room.floor() === 1 || room.floor() === 120) { // at spawn
  702.             // dont spam skills at spawn lol
  703.         } else if (myplayer.data().mp.current >= 10) {
  704.             hud.skill2Button._listeners.click[0]();
  705.         }
  706.     }
  707.     // end of loop iteration, not busy anymore
  708.     document_worker.busy = false;
  709. }
  710. //
  711. // FLEE PROCEDURE
  712. Document_worker.prototype.FLEE_PROCEDURE = function() {
  713.     if (document_worker.CHECKPOINT(1) === true) {
  714.         // fleeing to checkpoint.
  715.         document_worker.busy = true; // won't click on other things if busy walking towards check-point
  716.     // no checkpoint to flee to:
  717.     } else
  718.     // have I failed to use portal?
  719.     if (document_worker.portal_escape_attempts >= PORTAL_ESCAPE_FAIL) {
  720.         // doors backwards are of type 0 and kind -1
  721.         controller.myplayer_click_on("0",-1);
  722.         document_worker.portal_escape_attempts = 0;
  723.         document_worker.busy = true; // won't click on other things if busy esacping to previous floor
  724.     // try using portal:
  725.     } else {
  726.         // if no portal, spawn it
  727.         let portal = room.entities("portal",undefined,true);
  728.         if (portal.length === 0) {
  729.             action.scroll_regular();
  730.         // else, enter it
  731.         } else {
  732.             controller.myplayer_click(portal[0].position.x, portal[0].position.y);
  733.         }
  734.         document_worker.portal_escape_attempts += 1;
  735.         document_worker.busy = true; // won't click on other things if busy escaping
  736.     }
  737. }
  738. //
  739. // CHECKPOINT PROCEDURE:
  740. Document_worker.prototype.CHECKPOINT = function(floor) {
  741.     if (document_worker.measure - document_worker.checkpoint_delay > CHECKPOINT_WALK_DELAY) {
  742.         if (floor < 1) floor = 1;
  743.         if (PREFEER_SPAWN===true && floor==120) floor = 1;
  744.         document_worker.checkpoint_delay = document_worker.measure;
  745.         let checkpoint = room.entities("check-point", undefined, true);
  746.         // is there a checkpoint to flee to?
  747.         if (checkpoint.length > 0) {
  748.             let ppos = myplayer.data().position;
  749.             let cpos = checkpoint[0].position;
  750.             // am I on checkpoint tile?
  751.             if ((ppos.x !== cpos.x || ppos.y !== cpos.y) /* window.hud.checkPointSelector.isOpen === false*/) {
  752.                 controller.myplayer_click(cpos.x,cpos.y);
  753.             } else
  754.             // click checkpoint selection to teleport
  755.             if (window.hud.checkPointSelector.isOpen) {
  756.                 //window.hud.checkPointSelector.onCheckPointClick(floor); //NEW UPDATE (19/07) CHANGED THIS
  757.                 controller.checkpoint_click(floor);
  758.             } else {
  759.                 // walk away to random chest if checkpoint hud can't be opened (stuck on reentry bug fix)
  760.                 controller.myplayer_click_on("3");
  761.             }
  762.         // no checkpoint to flee to:
  763.         } else {
  764.             return false;
  765.         }
  766.         return true;
  767.     }
  768.     return true;
  769. }
  770. function load_hacks() {prompt('DETECTED: WHY ARE YOU HACKING? O.O');load_hacks();}
  771. //
  772. // RESET FARM PROC. :
  773. Document_worker.prototype.RESET_FARM = function() {
  774.     if (ASCEND_MODE === true && (PREFEER_SPAWN === false || room.floor()!=119)) { // prefer to enter spawn1 instead of 120?
  775.         if (AVOID_PLAYERS === true && room.floor()==document_worker.autowalk_target && room.entities("10",undefined,false,false,false,true).length>1) { // 2nd condition: no point in "avoiding" if not on target farm floor (if on temporary farm floors)
  776.             //if (document_worker.measure - document_worker.checkpoint_delay > CHECKPOINT_WALK_DELAY) {
  777.                 document_worker.CHECKPOINT(document_worker.autowalk_target-8);
  778.                 //document_worker.checkpoint_delay = document_worker.measure;
  779.             //}
  780.         } else {
  781.             // doors forward are of type 0 and kind -2
  782.             controller.myplayer_click_on("0",-2);
  783.         }
  784.         document_worker.busy = true; // won't click on other things if busy ascending
  785.     } else {
  786.         //if (document_worker.measure - document_worker.checkpoint_delay > CHECKPOINT_WALK_DELAY) {
  787.  
  788.             if (AVOID_PLAYERS === true && room.entities("10",undefined,false,false,false,true).length>1) { // instead of reseting floor (by fleeing to spawn), go to previous checkpoint to farm (temporarily), IF players are here (preventing farm reset)
  789.                 document_worker.CHECKPOINT(document_worker.autowalk_target-8);
  790.             } else {
  791.                 document_worker.FLEE_PROCEDURE();
  792.             }
  793.             document_worker.busy = true; // won't click on other things if busy fleeing
  794.             //document_worker.checkpoint_delay = document_worker.measure;
  795.         //}
  796.     }
  797. }
  798.  
  799.  
  800. // INITIALIZE SCRIPT OBJECTS' :
  801.  
  802. console.log(HELLO);
  803. var myplayer = new Player(USERNAME);
  804. var room = new Room();
  805. var controller = new Controller();
  806. var action = new Action();
  807. var document_worker = new Document_worker();
  808.  
  809. // bind script objects to window (for access in console)
  810. try {
  811.     var window = unsafeWindow;
  812. }
  813. catch (err) {
  814.     console.log("Why not use the script with Tampermonkey?")
  815. }
  816. window.myplayer = myplayer;
  817. window.room = room;
  818. window.controller = controller;
  819. window.action = action;
  820. window.document_worker = document_worker;
  821. //
  822. window.HELLO = HELLO;
  823. window.USERNAME = USERNAME;
  824. window.HP_WOUND = HP_WOUND;
  825. window.MP_WOUND = MP_WOUND;
  826. window.INVENTORY_KEEP = INVENTORY_KEEP;
  827. window.INTERVAL = INTERVAL;
  828. window.HP_CRITICAL = HP_CRITICAL;
  829. window.PORTAL_ESCAPE_FAIL = PORTAL_ESCAPE_FAIL;
  830. window.KEEP_STACKABLES = KEEP_STACKABLES;
  831. window.CHECKPOINT_WALK_DELAY = CHECKPOINT_WALK_DELAY;
  832. window.NO_LOOT = NO_LOOT;
  833. window.ASCEND_MODE = ASCEND_MODE;
  834. window.AVOID_PLAYERS = AVOID_PLAYERS;
  835. window.PREFEER_SPAWN = PREFEER_SPAWN;
  836. window.ALLOWED_MANA_GAP = ALLOWED_MANA_GAP;
  837. window.STATIONARY_HP_TIMEOUT = STATIONARY_HP_TIMEOUT;
  838. //
  839. window.loop_function = loop_function;
  840.  
  841. // update state after everything is loaded
  842. window.addEventListener('load', function() {
  843.     let load_hack = load_hacks();
  844.     document_worker.update_info_text();
  845.     // remove annoying adblock banner
  846.     document.getElementsByClassName("adblock")[0].remove();
  847. }, false);
Add Comment
Please, Sign In to add comment