Flight Rising Baldwin

Automatically transmutes items from your list.

  1. // ==UserScript==
  2. // @name Flight Rising Baldwin
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.0
  5. // @description Automatically transmutes items from your list.
  6. // @author Triggernometry
  7. // @match https://www1.flightrising.com/trading/baldwin/transmute*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @license GNU GPLv3
  11. // ==/UserScript==
  12.  
  13. // wait until page load, then run main
  14. $(document).ready(main);
  15.  
  16. // Categories are food, mats, app, fam, other
  17.  
  18. var transmuteItems = {
  19. "food" : [],
  20. "mats" : [],
  21. "app" : [],
  22. "fam" : [],
  23. "other" : []
  24. };
  25.  
  26. // set this to true to automatically melt down all food items with a point value of 2.
  27. // the script will check the list if it doesn't find any 2-value food items, so you can still fill out the list if you use this option.
  28. var autoMeltFood = false;
  29.  
  30. // these are used across all/most functions
  31. var toggleState = GM_getValue('toggleState', false);
  32. var toggleDisplay = ["OFF (click to toggle)",
  33. "ON (click to toggle)"];
  34.  
  35. function buildGUI() {
  36. console.log("toggleDisplay:", toggleDisplay);
  37. // set up GUI box
  38. $('body').prepend("<div id=\"familiarbox\">" +
  39. " <div style=\"text-align: center; color: #e8cc9f; font: bold 7.8pt/30px tahoma; background: #731d08; margin: -10px -10px 10px;\">Auto Brewing</div>" +
  40. // set toggle display to whatever it was before new page was loaded (or off, if page has never beeen loaded this session)
  41. " <button id=\"onOffDisplay\">" + toggleDisplay[toggleState ? 1 : 0] + "</button>" +
  42. "</div>" +
  43. "<style>" +
  44. " #familiarbox label {" +
  45. " float: inherit;" +
  46. " }" +
  47. " #familiarbox {" +
  48. " padding: 10px;" +
  49. " border: 1px solid #000;" +
  50. " position: fixed;" +
  51. " top: 0;" +
  52. " left: 0;" +
  53. " background: #fff;" +
  54. " z-index: 1002;" +
  55. " }" +
  56. " #turnOff," +
  57. " #turnOn {" +
  58. " border: 0;" +
  59. " background-color: #dcd6c8;" +
  60. " padding: 5px 10px;" +
  61. " color: #731d08;" +
  62. " margin: auto;" +
  63. " box-shadow: 0 1px 3px #999;" +
  64. " border-radius: 5px;" +
  65. " text-shadow: 0 1px 1px #FFF;" +
  66. " border-bottom: 1px solid #222;" +
  67. " cursor: pointer;" +
  68. " display: block;" +
  69. " font: bold 11px arial;" +
  70. " transition: 0.1s;" +
  71. " }" +
  72. " #onOffDisplay {" +
  73. " border: 0;" +
  74. " background-color: #dcd6c8;" +
  75. " padding: 5px 10px;" +
  76. " color: #731d08;" +
  77. " margin: auto;" +
  78. " box-shadow: 0 1px 3px #999;" +
  79. " border-radius: 5px;" +
  80. " text-shadow: 0 1px 1px #FFF;" +
  81. " border-bottom: 1px solid #222;" +
  82. " cursor: pointer;" +
  83. " display: block;" +
  84. " font: bold 11px arial;" +
  85. " transition: 0.1s;" +
  86. " }" +
  87. " #turnOff:hover," +
  88. " #turnOn:hover {" +
  89. " background-color: #bfb9ac;" +
  90. " color: #731d08;" +
  91. " }" +
  92. "</style>"
  93. );
  94.  
  95. // set the toggle click behavior
  96. $('#onOffDisplay').click(function(){
  97. toggleState = !toggleState;
  98. GM_setValue('toggleState', toggleState);
  99.  
  100. if(toggleState) {
  101. $('#onOffDisplay').html(toggleDisplay[1]);
  102. }
  103. else {
  104. $('#onOffDisplay').html(toggleDisplay[0]);
  105. }
  106. });
  107. }
  108.  
  109. async function getFood(maxPoints) {
  110. // switch to food category tab, if not already selected
  111. while(document.querySelector('#swaptabs > a[data-tab-id="food"]').className != 'generic-hoard-tab generic-hoard-tab-selected') {
  112. console.log("Swapping to food tab");
  113. let chooseCategory = document.querySelector('#swaptabs > a[data-tab-id="food"]').click();
  114. await sleep(2000);
  115. }
  116.  
  117. // get all items in category
  118. let itemList = document.querySelectorAll('#itempage > span > a');
  119.  
  120. // compare to own list of allowed items
  121. for (const node of itemList) {
  122. // get tooltip name
  123. var tooltipID = node.getAttribute('rel');
  124. // get first matching tooltip. this might fail if similar tooltips exist, like #17 and #177? need to test
  125. var tooltip = document.querySelectorAll(`${tooltipID} .foodval > strong`)[0];
  126. //console.log("Tooltip", tooltipID, "Foodval", tooltip.firstChild.data);
  127. var foodPoints = Number(tooltip.firstChild.data);
  128.  
  129. if(foodPoints <= maxPoints ) {
  130. // if allowed item found, set and break loop
  131. console.log("Found food:", node);
  132. return node;
  133. }
  134. }
  135.  
  136. //if reached end of loop without returning, no valid food found
  137. return null;
  138. }
  139.  
  140. async function getMatchingTransmutable() {
  141. for (const key of Object.keys(transmuteItems)) {
  142. let valueList = transmuteItems[key];
  143. console.log("key:", key);
  144. // switch to category tab
  145. let chooseCategory = document.querySelector(`#swaptabs > a[data-tab-id="${key}"]`).click();
  146. await sleep(2000);
  147.  
  148. // get all items in category
  149. let itemList = document.querySelectorAll('#itempage > span > a');
  150.  
  151. // compare to own list of allowed items
  152. for (const node of itemList) {
  153. if(valueList.includes(node.getAttribute('data-name'))) {
  154. // if allowed item found, return and break loops
  155. return node;
  156. }
  157. }
  158. }
  159.  
  160. //if reached end of loop without returning, no item found
  161. return null;
  162. }
  163.  
  164. async function collectItem(){
  165. await sleep(2000);
  166. let collectDoneItem = document.querySelector('input[value="Collect!"]').click();
  167. // wait for page to load after click
  168. // await collectDoneItem.DOMContentLoaded();
  169. await sleep(2000);
  170. location.reload();
  171. }
  172.  
  173. async function brewingWait(){
  174. let brewingTime = document.querySelector('#baldwin-timer-value').getAttribute('data-seconds-left');
  175. brewingTime = parseInt(brewingTime) + 3;
  176. console.log(`Now waiting for ${brewingTime} seconds. Please Stand by.`)
  177. await sleep(brewingTime * 1000);
  178. location.reload();
  179. }
  180.  
  181. async function transmute(){
  182. let clickTransmuteButton = document.querySelector('#baldwin-transmute-btn');
  183. console.log("Click return object:", clickTransmuteButton);
  184.  
  185. // wait for item load
  186. // if Transmute button is clicked multiple times, page breaks
  187. while(!document.querySelector('#ui-id-1'))
  188. {
  189. await sleep(2000);
  190. clickTransmuteButton.click();
  191. await sleep(2000);
  192. }
  193.  
  194. var transmuteSelection;
  195.  
  196. if (autoMeltFood) {
  197. transmuteSelection = await getFood(2);
  198. }
  199.  
  200. if (!transmuteSelection) {
  201. transmuteSelection = await getMatchingTransmutable();
  202. }
  203.  
  204. // if not null, item found
  205. if(transmuteSelection) {
  206. console.log("Selected food:", transmuteSelection);
  207.  
  208. transmuteSelection.click();
  209. await sleep(1000);
  210. let transmuteStart = document.querySelector('#attch').click();
  211. await sleep(2000);
  212. let transmuteConfirm = document.querySelector('#transmute-confirm-ok').click();
  213. }
  214. // otherwise, reached end of items without findin a match. Exit.
  215. else {
  216. console.log("Reached end without finding a match. Nothing to brew.");
  217. return 0;
  218. }
  219. }
  220.  
  221. function sleep(ms) {
  222. console.log(`Sleebs ${ms} ms!`);
  223. return new Promise(resolve => setTimeout(resolve, ms));
  224. }
  225.  
  226. function main(){
  227. buildGUI();
  228.  
  229. // only if on
  230. if (toggleState == true){
  231. let idle = document.querySelector('#plus-button-container');
  232. let brewing = document.querySelector('.baldwin-cauldron-brewing');
  233. let done = document.querySelector('.baldwin-cauldron-done');
  234.  
  235. if(done){
  236. collectItem();
  237. } else if (brewing){
  238. brewingWait();
  239. } else if(idle){
  240. transmute();
  241. }
  242. }
  243. }