Autosmash

Choose items to pulverize. Pulverize all of them with one click.

  1. // ==UserScript==
  2. // @name Autosmash
  3. // @namespace kingdomofloathing.com
  4. // @author benjy___mouse
  5. // @description Choose items to pulverize. Pulverize all of them with one click.
  6. // @include http://*kingdomofloathing.com/craft.php*
  7. // @include http://*kingdomofloathing.com/account.php*
  8. // @include http://127.0.0.1:*/craft.php*
  9. // @include http://127.0.0.1:*/account.php*
  10. // @version 01/2015
  11. // @grant GM_log
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // @grant GM_xmlhttpRequest
  15. // @grant GM_registerMenuCommand
  16. // ==/UserScript==
  17.  
  18. // GREASEMONKEY VALUES:
  19. // smashables -- user-editable list of items marked for autosmashing
  20. // activeSession -- is there currently an autosmash session in progress?
  21. // sessionQueue -- temporary script-editable copy of "smashables"
  22.  
  23. // How to use this script: Go to your account menu, click the "Autosmash" tab,
  24. // and type the names of the items you want to autosmash. Click "Save". Then
  25. // go to your crafting menu, click [smith stuff] if necessary. You should see
  26. // a gray button with white text that says "Autosmash!". Click it!
  27.  
  28. // This script will smash ALL the items that you mark for autosmashing. There
  29. // is currently no option to smash only one, smash all but one, etc. There is
  30. // currently no support for different preferences for different characters. If
  31. // you have other scripts modifying your [smith stuff] page, there is a good
  32. // chance something will go horribly wrong. Happy smashing!
  33.  
  34. /********************************** RUNTIME **********************************/
  35.  
  36. // figure out what KoL page we're on
  37. switch(document.location.pathname)
  38. {
  39. case "/account.php":
  40. accountAction();
  41. break;
  42.  
  43. case "/craft.php":
  44. if (document.querySelector("input").value == "smith")
  45. craftAction(false);
  46. break;
  47.  
  48. default: // do nothing if on irrelevant page
  49. }
  50.  
  51. /************** ACCOUNT MENU FUNCTIONS: AUTOSMASH CONFIGURATION **************/
  52.  
  53. // make autosmash tab in account menu. major credit to the UpUp.us Auto Choice
  54. // script, from which i copied most of this code.
  55. function accountAction()
  56. {
  57. var optionsList = document.querySelector("ul");
  58. var autosmashTab = document.createElement("li");
  59. autosmashTab.id = "autosmash";
  60. var tabLabel = document.createElement("a");
  61. tabLabel.href = "#";
  62. var img = tabLabel.appendChild(document.createElement("img"));
  63. img.src = "http://images.kingdomofloathing.com/itemimages/hammer.gif"
  64. tabLabel.appendChild(document.createTextNode("Autosmash"));
  65. autosmashTab.appendChild(tabLabel);
  66. optionsList.appendChild(autosmashTab);
  67.  
  68. tabLabel.addEventListener('click', function (e)
  69. {
  70. e.stopPropagation();
  71. document.querySelector(".active").className = "";
  72. document.querySelector("#autosmash").className = "active";
  73. document.querySelector("#guts").innerHTML = "<div class='scaffold'></div>";
  74. document.querySelector("#guts").appendChild(showList());
  75. }, false);
  76. }
  77.  
  78. // show editable list of items for autosmashing
  79. function showList()
  80. {
  81. var guts = document.body.appendChild(document.createElement('div'));
  82.  
  83. var helpMessage = document.createTextNode("Type the items you want to autosmash "
  84. + "into the text box. One item per line. Use the complete name, just as it "
  85. + "appears in the game, including capital letters, spaces, and punctuation. "
  86. + "It doesn't autosave, so make sure you click 'Save' when you're done.");
  87. guts.appendChild(helpMessage);
  88. guts.appendChild(document.createElement("p"));
  89.  
  90. // textarea where you write the items you want to smash
  91. var autosmashList = document.createElement("textarea");
  92. autosmashList.style.width = "90%";
  93. autosmashList.rows = 16;
  94. autosmashList.value = GM_getValue("smashables", "");
  95. guts.appendChild(autosmashList);
  96. guts.appendChild(document.createElement("p"));
  97.  
  98. // "Save" button
  99. var submitButton = document.createElement("button");
  100. submitButton.style.border = "2px black solid";
  101. submitButton.style.padding = "3px";
  102. submitButton.style.fontFamily = "arial";
  103. submitButton.style.fontSize = "10pt";
  104. submitButton.style.fontWeight = "bold";
  105. submitButton.style.color = "black";
  106. submitButton.style.background = "white";
  107. submitButton.appendChild(document.createTextNode("Save"));
  108. guts.appendChild(submitButton);
  109.  
  110. submitButton.addEventListener('click', function (e)
  111. {
  112. e.stopPropagation();
  113. e.preventDefault();
  114. GM_setValue("smashables", autosmashList.value);
  115. var resultMessage = document.createTextNode(" Autosmash preferences saved!");
  116. guts.appendChild(resultMessage);
  117. }, false);
  118.  
  119. return guts;
  120. }
  121.  
  122. /**************** CRAFTING MENU FUNCTIONS: AUTOSMASH EXECUTION ****************/
  123.  
  124. // check if we're curently in the middle of an autosmash session
  125. function craftAction(reloading)
  126. {
  127. if (GM_getValue("activeSession", false))
  128. execute();
  129. // check if the smithing page has been reloaded; this prevents the creation
  130. // of duplicate autosmash buttons
  131. else if (!reloading)
  132. showButton();
  133. }
  134.  
  135. // make the autosmash button and put it in the middle of the page
  136. function showButton()
  137. {
  138. var smashMenu = document.getElementsByTagName("p")[4];
  139. var autosmashButton = document.createElement("button");
  140. autosmashButton.style.border = "2px black solid";
  141. autosmashButton.style.padding = "3px";
  142. autosmashButton.style.fontFamily = "arial";
  143. autosmashButton.style.fontSize = "10pt";
  144. autosmashButton.style.fontWeight = "bold";
  145. autosmashButton.style.color = "white";
  146. autosmashButton.style.background = "#555555";
  147. autosmashButton.appendChild(document.createTextNode("Autosmash!"));
  148. smashMenu.appendChild(autosmashButton);
  149.  
  150. // when the user clicks the autosmash button, create a temporary copy of the
  151. // list of autosmashable items (which the user typed into the account menu)
  152. // and begin a new autosmash session
  153. autosmashButton.addEventListener('click', function (e)
  154. {
  155. e.stopPropagation();
  156. e.preventDefault();
  157. GM_setValue("activeSession", true);
  158. GM_setValue("sessionQueue", GM_getValue("smashables", ""));
  159. execute();
  160. }, false);
  161. }
  162.  
  163. // loop through the dropdown of pulverizable items, searching for a match for each
  164. // entry in the list of autosmashable items. binary search would be faster here but
  165. // i can't be bothered to implement it. this function runs once for each item in
  166. // the list of autosmashables.
  167. function execute()
  168. {
  169. // dequeue the first item from the list of autosmashables
  170. var smashQueue = GM_getValue("sessionQueue", "");
  171. var m = smashQueue.indexOf("\n");
  172. if (m == -1) // last autosmashable item reached, end autosmash session
  173. {
  174. var smashTarget = smashQueue;
  175. GM_setValue("activeSession", false);
  176. alert("Autosmash complete!");
  177. }
  178. else
  179. {
  180. var smashTarget = smashQueue.slice(0, m);
  181. GM_setValue("sessionQueue", smashQueue.slice(m+1));
  182. }
  183.  
  184. // find the quantity field and the "Pulverize!" button on the page
  185. var pulverizeQtyFld = document.getElementsByName("qty")[1];
  186. var pulverizeButton = document.getElementsByClassName("button")[1];
  187.  
  188. // parse dropdown of pulverizable items in inventory
  189. var itemArray = document.getElementsByName("smashitem")[0]; // returns a <select>
  190. var n = itemArray.options.length;
  191. var itemString = [];
  192. var itemName = "";
  193. var itemQty = 0;
  194.  
  195. // don't start at i = 0 because the first option is "-select an item-"
  196. for (i = 1; i < n; i++)
  197. {
  198. // separate out item name and item quantity
  199. itemString = itemArray.options[i].text.split("(");
  200. itemName = itemString[0].slice(0, -1); // remove trailing space
  201. itemQty = itemString[1].slice(0, -1); // remove trailing close parenthesis
  202.  
  203. // smashing time!
  204. if (itemName == smashTarget)
  205. {
  206. var successfulSmash = true;
  207. itemArray.options[i].selected = true;
  208. pulverizeQtyFld.value = itemQty;
  209. pulverizeButton.click();
  210. }
  211. }
  212. // continue script if no matches found
  213. if (!successfulSmash)
  214. craftAction(true);
  215. }