Advertisement
Guest User

Evolve Automation Script Variant

a guest
Jan 18th, 2021
3,870
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 297.43 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Evolve
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3
  5. // @description Edited slightly by CondoSlime
  6. // @author Fafnir
  7. // @match https://pmotschmann.github.io/Evolve/
  8. // @grant GM_log
  9. // @require https://code.jquery.com/jquery-3.3.1.min.js
  10. // ==/UserScript==
  11.  
  12. (function($) {
  13. 'use strict';
  14. var settings = {};
  15. var jsonSettings = localStorage.getItem('settings');
  16. if(jsonSettings != null){
  17. settings = JSON.parse(jsonSettings);
  18. }
  19.  
  20. /***
  21. *
  22. * Setup resources informations and settings
  23. *
  24. ***/
  25.  
  26. // Theoretically used to make sure script clicks don't have the modifier keys
  27. // However, can just turn off multiplier keys
  28. var ctrlDown = false;
  29. var altDown = false;
  30. var shiftDown = false;
  31.  
  32. /*
  33. document.onkeydown = function(e) {
  34. if (e.key == "Control") {
  35. ctrlDown = true;
  36. }
  37. if (e.key == "Alt") {
  38. altDown = true;
  39. }
  40. if (e.key == "Shift") {
  41. shiftDown = true;
  42. }
  43. };
  44. document.onkeyup = function(e) {
  45. if (e.key == "Control") {
  46. ctrlDown = false;
  47. }
  48. if (e.key == "Alt") {
  49. altDown = false;
  50. }
  51. if (e.key == "Shift") {
  52. shiftDown = false;
  53. }
  54. };*/
  55.  
  56. // Used to ensure no modal window conflicts
  57. let modal = false;
  58.  
  59. class Resource {
  60. constructor(name, id, storePriority, storeMin) {
  61. this.name = name;
  62. this.id = id;
  63. if (!settings.resources.hasOwnProperty(this.id)) {settings.resources[this.id] = {};}
  64. if (!settings.resources[this.id].hasOwnProperty('storeMin')) {settings.resources[this.id].storeMin = storeMin;}
  65. if (!settings.resources[this.id].hasOwnProperty('storePriority')) {settings.resources[this.id].storePriority = storePriority;}
  66.  
  67. }
  68. get storeMin() {return settings.resources[this.id].storeMin;}
  69. set storeMin(storeMin) {settings.resources[this.id].storeMin = storeMin;}
  70. get storePriority() {return settings.resources[this.id].storePriority};
  71. set storePriority(storePriority) {settings.resources[this.id].storePriority = storePriority;}
  72.  
  73. get amount() {
  74. try {
  75. return getRealValue($('#cnt'+this.id)[0].innerHTML.split(' / ')[0]);
  76. } catch(e) {
  77. console.log("Error: Resource", this.name, "Amount invalid");
  78. return null;
  79. }
  80. }
  81.  
  82. get crateable() {
  83. try {
  84. return ($('#con'+this.id)[0] !== undefined);
  85. } catch(e) {
  86. console.log("Error:", this.id, "Crateable");
  87. return null;
  88. }
  89. }
  90. get storage() {
  91. try {
  92. return getRealValue($('#cnt'+this.id)[0].innerHTML.split(' / ')[1]);
  93. } catch(e) {
  94. console.log("Error: Resource", this.name, "Storage invalid");
  95. return null;
  96. }
  97. }
  98.  
  99. get ratio() {
  100. return this.amount / this.storage;
  101. }
  102.  
  103. get unlocked() {
  104. try {
  105. return $('#res'+this.id)[0].style.display != 'none';
  106. } catch(e) {
  107. return false;
  108. }
  109. }
  110.  
  111. get rate() {
  112. try {
  113. return getRealValue($('#inc'+this.id)[0].innerText.substr(0, $('#inc'+this.id)[0].innerText.length - 3))
  114. } catch(e) {
  115. return null;
  116. }
  117. }
  118. decStoreMin() {
  119. if (this.storeMin == 0) {return;}
  120. this.storeMin -= 1;
  121. updateSettings();
  122. console.log("Decrementing Store Minimum", this.id, this.storeMin);
  123. }
  124. incStoreMin() {
  125. if (this.storeMin == 99) {return;}
  126. this.storeMin += 1;
  127. updateSettings();
  128. console.log("Incrementing Store Minimum", this.id, this.storeMin);
  129. }
  130. decStorePriority() {
  131. if (this.storePriority == 0) {return;}
  132. this.storePriority -= 1;
  133. updateSettings();
  134. console.log("Decrementing Store Priority", this.id, this.storePriority);
  135. }
  136. incStorePriority() {
  137. if (this.storePriority == 99) {return;}
  138. this.storePriority += 1;
  139. updateSettings();
  140. console.log("Incrementing Store Priority", this.id, this.storePriority);
  141. }
  142. }
  143.  
  144. class TradeableResource extends Resource {
  145. constructor(name, id, autoBuy, autoSell, buyRatio, sellRatio, storePriority, storeMin) {
  146. super(name, id, storePriority, storeMin);
  147. if (!settings.resources.hasOwnProperty(this.id)) {settings.resources[this.id] = {};}
  148. if (!settings.resources[this.id].hasOwnProperty('autoSell')) {settings.resources[this.id].autoSell = autoSell;}
  149. if (!settings.resources[this.id].hasOwnProperty('autoBuy')) {settings.resources[this.id].autoBuy = autoBuy;}
  150. if (!settings.resources[this.id].hasOwnProperty('buyRatio')) {settings.resources[this.id].buyRatio = buyRatio;}
  151. if (!settings.resources[this.id].hasOwnProperty('sellRatio')) {settings.resources[this.id].sellRatio = sellRatio;}
  152. }
  153.  
  154. get autoSell() {return settings.resources[this.id].autoSell};
  155. set autoSell(autoSell) {settings.resources[this.id].autoSell = autoSell;}
  156. get autoBuy() {return settings.resources[this.id].autoBuy};
  157. set autoBuy(autoBuy) {settings.resources[this.id].autoBuy = autoBuy;}
  158. get buyRatio() {return settings.resources[this.id].buyRatio};
  159. set buyRatio(buyRatio) {settings.resources[this.id].buyRatio = buyRatio;}
  160. get sellRatio() {return settings.resources[this.id].sellRatio};
  161. set sellRatio(sellRatio) {settings.resources[this.id].sellRatio = sellRatio;}
  162.  
  163.  
  164. get sellBtn (){ return $('#market-'+this.id+' .order')[1];}
  165. get buyBtn (){ return $('#market-'+this.id+' .order')[0];}
  166.  
  167. buyDec() {
  168. if (this.buyRatio > 0) {
  169. this.buyRatio = parseFloat(Number(this.buyRatio - 0.1).toFixed(1));
  170. updateSettings();
  171. console.log(this.id, "Decrementing Buy Ratio", this.buyRatio);
  172. }
  173. }
  174. buyInc() {
  175. if (this.buyRatio < 1) {
  176. this.buyRatio = parseFloat(Number(this.buyRatio + 0.1).toFixed(1));
  177. updateSettings();
  178. console.log(this.id, "Incrementing Buy Ratio", this.buyRatio);
  179. }
  180. }
  181. sellDec() {
  182. if (this.sellRatio > 0) {
  183. this.sellRatio = parseFloat(Number(this.sellRatio - 0.1).toFixed(1));
  184. updateSettings();
  185. console.log(this.id, "Decrementing Sell Ratio", this.sellRatio);
  186. }
  187. }
  188. sellInc() {
  189. if (this.sellRatio < 1) {
  190. this.sellRatio = parseFloat(Number(this.sellRatio + 0.1).toFixed(1));
  191. console.log(this.id, "Incrementing Sell Ratio", this.sellRatio);
  192. }
  193. }
  194.  
  195. tradeDec() {
  196. try {
  197. $('#market-'+this.id+' > .trade > .is-primary')[1].children[0].click();
  198. } catch(e) {
  199. console.log("Error:", this.id, "Trade Decrement");
  200. return null;
  201. }
  202. }
  203. tradeInc() {
  204. try {
  205. $('#market-'+this.id+' > .trade > .is-primary')[0].children[0].click();
  206. } catch(e) {
  207. console.log("Error:", this.id, "Trade Increment");
  208. return null;
  209. }
  210. }
  211.  
  212. get tradeNum() {
  213. try {
  214. return parseInt($('#market-'+this.id+' > .trade > .current')[0].innerText);
  215. } catch(e) {
  216. console.log("Error:", this.id, "Trade Num");
  217. return null;
  218. }
  219. }
  220. get tradeBuyCost() {
  221. try {
  222. let dataStr = $('#market-'+this.id+' > .trade > .is-primary')[0].attributes['data-label'].value;
  223. var reg = /Auto-buy\s([\d\.]+)[\w\s]*\$([\d\.]+)/.exec(dataStr);
  224. return parseFloat(reg[2]);
  225. } catch(e) {
  226. console.log("Error:", this.id, "Trade Buy Cost");
  227. return null;
  228. }
  229. }
  230. get tradeSellCost() {
  231. try {
  232. let dataStr = $('#market-'+this.id+' > .trade > .is-primary')[1].attributes['data-label'].value;
  233. var reg = /Auto-sell\s([\d\.]+)[\w\s]*\$([\d\.]+)/.exec(dataStr);
  234. return parseFloat(reg[2]);
  235. } catch(e) {
  236. console.log("Error:", this.id, "Trade Sell Cost");
  237. return null;
  238. }
  239. }
  240. get tradeAmount() {
  241. try {
  242. let dataStr = $('#market-'+this.id+' > .trade > .is-primary')[1].attributes['data-label'].value;
  243. var reg = /Auto-sell\s([\d\.]+)[\w\s]*\$([\d\.]+)/.exec(dataStr);
  244. return parseFloat(reg[1]);
  245. } catch(e) {
  246. console.log("Error:", this.id, "Trade Amount");
  247. return null;
  248. }
  249. }
  250.  
  251. openStorage() {
  252. try {
  253. let storageBtn = $('#con'+this.id)[0];
  254. storageBtn.click();
  255. } catch(e) {
  256. console.log("Error:", this.id, "OpenStorage");
  257. }
  258. }
  259.  
  260.  
  261. }
  262. var resources = [];
  263. var resourcesArr = [];
  264. function loadResources() {
  265. if (!settings.hasOwnProperty('resources')) {settings.resources = {};}
  266. resources.Money = new Resource("Money", "Money", 0, 0);
  267. resources.Knowledge = new Resource("Knowledge", "Knowledge", 0, 0);
  268. resources.Food = new TradeableResource("Food", "Food", false, false, .5, .9, 0, 0);
  269. resources.Lumber = new TradeableResource("Lumber", "Lumber", false, false, .5, .9, 3, 0);
  270. resources.Stone = new TradeableResource("Stone", "Stone", false, false, .5, .9, 3, 0);
  271. resources.Furs = new TradeableResource("Furs", "Furs", false, false, .5, .9, 2, 0);
  272. resources.Copper = new TradeableResource("Copper", "Copper", false, false, .5, .9, 2, 0);
  273. resources.Iron = new TradeableResource("Iron", "Iron", false, false, .5, .9, 2, 0);
  274. resources.Aluminium = new TradeableResource("Aluminium", "Aluminium", false, false, .5, .9, 2, 0);
  275. resources.Cement = new TradeableResource("Cement", "Cement", false, false, .5, .9, 2, 0);
  276. resources.Coal = new TradeableResource("Coal", "Coal", false, false, .5, .9, 0, 0);
  277. resources.Oil = new TradeableResource("Oil", "Oil", false, false, .5, .9, 0, 0);
  278. resources.Uranium = new TradeableResource("Uranium", "Uranium", false, false, .5, .9, 0, 0);
  279. resources.Steel = new TradeableResource("Steel", "Steel", false, false, .5, .9, 3, 10);
  280. resources.Titanium = new TradeableResource("Titanium", "Titanium", false, false, .5, .9, 3, 10);
  281. resources.Alloy = new TradeableResource("Alloy", "Alloy", false, false, .5, .9, 3, 10);
  282. resources.Polymer = new TradeableResource("Polymer", "Polymer", false, false, .5, .9, 3, 10);
  283. resources.Iridium = new TradeableResource("Iridium", "Iridium", false, false, .5, .9, 3, 10);
  284. resources.Helium_3 = new TradeableResource("Helium-3", "Helium_3", false, false, .5, .9, 0, 0);
  285.  
  286. resources.Infernite = new Resource("Infernite", "Infernite", 3, 0);
  287. resources.Adamantite = new Resource("Adamantite", "Adamantite", 3, 0);
  288. resources.Graphene = new Resource("Graphene", "Graphene", 3, 0);
  289. resources.Stanene = new Resource("Stanene", "Stanene", 3, 0);
  290.  
  291. for (let x in resources){
  292. resourcesArr.push(x);
  293. }
  294. }
  295.  
  296. class CraftableResource extends Resource {
  297. constructor(name, id, enabled, sources) {
  298. const storeMin = 0;
  299. super(name, id, storeMin);
  300. this.sources = sources;
  301. this.craftable = true;
  302. if (!settings.resources[this.id].hasOwnProperty('enabled')) {settings.resources[this.id].enabled = enabled;}
  303. }
  304.  
  305. get enabled() {return settings.resources[this.id].enabled;}
  306. set enabled(enabled) {settings.resources[this.id].enabled = enabled;}
  307.  
  308. get canCraft() {
  309. // Crafting if resource is unlocked and enabled
  310. if (this.unlocked && this.enabled) {
  311. // Checking if every source can be used
  312. //console.log("Checking crafting of", this);
  313. if (this.sources.every(function(element) {
  314. //console.log("Checking Resource", element.res, element.res.ratio);
  315. return element.res.ratio > 0.9;
  316. })) {
  317. //console.log("Can Craft", this.name);
  318. // Determining number of crafts
  319. let total_crafts = 100000000000;
  320. for (let i = 0;i < this.sources.length;i++) {
  321. let res = this.sources[i].res;
  322. let cost = this.sources[i].cost;
  323. let cur_crafts = Math.round((res.amount - (res.storage * .9)) / cost);
  324. //console.log("Checking", res.name, "A/S", res.amount, res.storage, cur_crafts);
  325. if (cur_crafts < total_crafts) {
  326. total_crafts = cur_crafts;
  327. }
  328. }
  329. return total_crafts;
  330. }
  331. }
  332. return 0;
  333. }
  334.  
  335. get rate() {
  336. //TODO: Somehow figure out how to find the rate (number of craftsmen can be found, but not how much per craftsman)
  337. return 0.000001;
  338. }
  339.  
  340. craft(num) {
  341. try {
  342. //console.log(this.id, this.unlocked, this.enabled, this.canCraft);
  343. if (!this.unlocked || !this.enabled) {return;}
  344. const res = document.getElementById("inc" + this.id + "5");
  345. if (!res) return;
  346. let craftBtn = res.getElementsByTagName("a")[0];
  347. if (craftBtn !== null) {
  348. for (let j = 0;j < this.canCraft;j++) {
  349. craftBtn.click();
  350. }
  351. }
  352. return true;
  353. } catch(e) {
  354. console.log("Error:", this.id, "Craft", e);
  355. return false;
  356. }
  357. }
  358. }
  359. var craftableResources = {};
  360. function loadCraftableResources() {
  361. if (!settings.hasOwnProperty('resources')) {settings.resources = {};}
  362. craftableResources.Plywood = new CraftableResource("Plywood", "Plywood", false, [{res:resources.Lumber,cost:500}]);
  363. craftableResources.Brick = new CraftableResource("Brick", "Brick", false, [{res:resources.Cement,cost:200}]);
  364. craftableResources.Wrought_Iron = new CraftableResource("Wrought Iron", "Wrought_Iron", false, [{res:resources.Iron,cost:400}]);
  365. craftableResources.Sheet_Metal = new CraftableResource("Sheet Metal", "Sheet_Metal", false, [{res:resources.Aluminium,cost:600}]);
  366. craftableResources.Mythril = new CraftableResource("Mythril", "Mythril", false, [{res:resources.Alloy,cost:500}, {res:resources.Iridium,cost:1250}]);
  367. craftableResources.Aerogel = new CraftableResource("Aerogel", "Aerogel", false, [{res:resources.Graphene,cost:2500}, {res:resources.Infernite,cost:50}]);
  368. }
  369.  
  370. function priorityScale(value, priority, action) {
  371. let scale = Math.exp(-0.25 * priority);
  372. if (action !== null && action !== undefined) {
  373. if (action instanceof Research) {
  374. scale / 2;
  375. }
  376. }
  377. return value * scale;
  378. }
  379. class Action {
  380. constructor(id, tags, priority) {
  381. this.id = id;
  382. this.tags = tags;
  383. if (!settings.actions.hasOwnProperty(this.id)) {settings.actions[this.id] = {};}
  384. if (!settings.actions[this.id].hasOwnProperty('priority')) {settings.actions[this.id].priority = priority;}
  385. }
  386.  
  387. get priority() {return settings.actions[this.id].priority;}
  388. set priority(priority) {settings.actions[this.id].priority = priority;}
  389.  
  390. get unlocked() {
  391. try {
  392. let label = $('#'+this.id+' > a > .aTitle')[0];
  393. return ($('#'+this.id+' > a > .aTitle')[0] !== undefined);
  394. } catch(e) {
  395. console.log("Error:", this.id, "Unlocked");
  396. return false;
  397. }
  398. }
  399.  
  400. get name() {
  401. try {
  402. let label = $('#'+this.id+' > a > .aTitle');
  403. if (label.length != 0) {
  404. return label[0].innerText;
  405. } else {
  406. return this.id;
  407. }
  408. } catch(e) {
  409. console.log("Error:", this.id, "Name");
  410. return null;
  411. }
  412. }
  413.  
  414. decPriority() {
  415. if (this.priority == -99) {return;}
  416. this.priority -= 1;
  417. updateSettings();
  418. console.log("Decrementing Priority", this.id, this.priority);
  419. }
  420.  
  421. incPriority() {
  422. if (this.priority == 99) {return;}
  423. this.priority += 1;
  424. updateSettings();
  425. console.log("Incrementing Priority", this.id, this.priority);
  426. }
  427.  
  428. getResDep(resid) {
  429. try {
  430. // Loading res
  431. this.res = {};
  432. let data = $('#' + this.id + ' > a')[0];
  433. for (let i = 0;i < data.attributes.length;i++) {
  434. let name = data.attributes[i].name;
  435. let cost = data.attributes[i].value;
  436. if (name.indexOf('data-') >= 0) {
  437. this.res[name.substr(5, name.length)] = parseInt(cost);
  438. }
  439. }
  440. return this.res[resid.toLowerCase()];
  441. } catch(e) {
  442. console.log("Error:", this.id, "getResDep");
  443. return null;
  444. }
  445. }
  446.  
  447. click() {
  448. try {
  449. let btn = document.getElementById(this.id);
  450. if (btn.className.indexOf('cna') < 0) {
  451. btn.getElementsByTagName("a")[0].click();
  452. return true;
  453. }
  454. return false;
  455. } catch(e) {
  456. console.log("Error:", this.id, "Click");
  457. return false;
  458. }
  459. return false;
  460. }
  461. }
  462.  
  463. class Building extends Action {
  464. constructor(id, tags, enabled, limit, priority) {
  465. super(id, tags, priority);
  466. if (!settings.actions[this.id].hasOwnProperty('enabled')) {settings.actions[this.id].enabled = enabled;}
  467. //if (!settings.actions[this.id].hasOwnProperty('limit')) {settings.actions[this.id].limit = limit;}
  468. settings.actions[this.id].limit = limit;
  469. }
  470.  
  471. get enabled() {return settings.actions[this.id].enabled;}
  472. set enabled(enabled) {settings.actions[this.id].enabled = enabled;}
  473. get limit() {return settings.actions[this.id].limit;}
  474. set limit(limit) {settings.actions[this.id].limit = limit;}
  475. get numTotal() {
  476. try {
  477. let amountLabel = $('#'+this.id+' > a > .count')[0];
  478. if (amountLabel !== undefined) {
  479. return parseInt(amountLabel.innerText);
  480. } else {
  481. return null;
  482. }
  483. } catch(e) {
  484. console.log("Error:", this.id, "numTotal");
  485. return null;
  486. }
  487. }
  488.  
  489. decLimit() {
  490. if (this.limit == -1) {return;}
  491. this.limit -= 1;
  492. updateSettings();
  493. console.log("Decrementing Limit", this.id, this.limit);
  494. }
  495.  
  496. incLimit() {
  497. if (this.limit == 99) {return;}
  498. this.limit += 1;
  499. updateSettings();
  500. console.log("Incrementing Limit", this.id, this.limit);
  501. }
  502.  
  503. }
  504. class PoweredBuilding extends Building {
  505. constructor(id, tags, enabled, limit, priority, powerPriority, consume, produce, unlockResearch) {
  506. super(id, tags, enabled, limit, priority);
  507. this.produce = produce;
  508. this.consume = consume;
  509. if (!settings.actions[this.id].hasOwnProperty('powerPriority')) {settings.actions[this.id].powerPriority = powerPriority;}
  510. this.unlockResearch = unlockResearch;
  511. }
  512.  
  513. get powerPriority() {return settings.actions[this.id].powerPriority;}
  514. set powerPriority(powerPriority) {settings.actions[this.id].powerPriority = powerPriority;}
  515.  
  516. get powerUnlocked() {
  517. try {
  518. if (this.unlockResearch !== undefined) {
  519. return $('#'+this.id).length > 0 && researched(this.unlockResearch);
  520. }
  521. return $('#'+this.id).length > 0;
  522. } catch(e) {
  523. console.log("Error:", this.id, "powerUnlocked");
  524. return false;
  525. }
  526. }
  527.  
  528. get numOn() {
  529. try {
  530. let incBtn = $('#'+this.id+' > .on')[0];
  531. return parseInt(incBtn.innerText);
  532. } catch(e) {
  533. console.log("Error:", this.id, "numOn");
  534. return null;
  535. }
  536. }
  537.  
  538. get numOff() {
  539. try {
  540. let decBtn = $('#'+this.id+' > .off')[0];
  541. return parseInt(decBtn.innerText);
  542. } catch(e) {
  543. console.log("Error:", this.id, "numOff");
  544. return null;
  545. }
  546. }
  547.  
  548. decPowerPriority() {
  549. if (this.power_priority == 0) {return;}
  550. this.power_priority -= 1;
  551. updateSettings();
  552. console.log("Decrementing Power Priority", this.id, this.power_priority);
  553. }
  554.  
  555. incPowerPriority() {
  556. if (this.power_priority == 99) {return;}
  557. this.power_priority += 1;
  558. updateSettings();
  559. console.log("Incrementing Priority", this.id, this.power_priority);
  560. }
  561. }
  562. var buildings = {};
  563. function loadBuildings() {
  564. if (!settings.hasOwnProperty('actions')) {settings.actions = {};}
  565. buildings['city-basic_housing'] = new Building('city-basic_housing',
  566. ['city', 'citizen'],
  567. false, -1, 2);
  568. buildings['city-cottage'] = new Building('city-cottage',
  569. ['city', 'citizen'],
  570. false, -1, 0);
  571. buildings['city-apartment'] = new PoweredBuilding('city-apartment',
  572. ['city', 'citizen', 'power'],
  573. false, -1, 5,
  574. 9,
  575. [{res:'electricity',cost:1}],
  576. []);
  577. buildings['city-lodge'] = new Building('city-lodge',
  578. ['city', 'citizen'],
  579. false, -1, 1);
  580. buildings['city-smokehouse'] = new Building('city-smokehouse',
  581. ['city', 'food'],
  582. false, -1, 1);
  583. buildings['city-soul_well'] = new Building('city-soul_well',
  584. ['city'],
  585. false, -1, 1);
  586. buildings['city-slave_pen'] = new Building('city-slave_pen',
  587. ['city'],
  588. false, -1, 1);
  589. buildings['city-farm'] = new Building('city-farm',
  590. ['city', 'food'],
  591. false, -1, 1);
  592. buildings['city-mill'] = new Building('city-mill',
  593. ['city', 'food'],
  594. false, -1, 1);
  595. buildings['city-windmill'] = new PoweredBuilding('city-windmill',
  596. ['city', 'food', 'power'],
  597. false, -1, 1,
  598. 9,
  599. [{res:resources.Food,cost:0.1}],
  600. [{res:'electricity',cost:1}]);
  601. buildings['city-silo'] = new Building('city-silo',
  602. ['city', 'food'],
  603. false, -1, 0);
  604. buildings['city-garrison'] = new Building('city-garrison',
  605. ['city', 'army'],
  606. false, -1, 4);
  607. buildings['city-hospital'] = new Building('city-hospital',
  608. ['city', 'army'],
  609. false, -1, 3);
  610. buildings['city-boot_camp'] = new Building('city-boot_camp',
  611. ['city', 'army'],
  612. false, -1, 3);
  613. buildings['city-shed'] = new Building('city-shed',
  614. ['city', 'storage'],
  615. false, -1, 2);
  616. buildings['city-storage_yard'] = new Building('city-storage_yard',
  617. ['city', 'storage'],
  618. false, -1, 0);
  619. buildings['city-warehouse'] = new Building('city-warehouse',
  620. ['city', 'storage'],
  621. false, -1, 0);
  622. buildings['city-bank'] = new Building('city-bank',
  623. ['city', 'money'],
  624. false, -1, 5);
  625. buildings['city-lumber_yard'] = new Building('city-lumber_yard',
  626. ['city'],
  627. false, -1, 1);
  628. buildings['city-graveyard'] = new Building('city-graveyard',
  629. ['city'],
  630. false, -1, 1);
  631. buildings['city-sawmill'] = new PoweredBuilding('city-sawmill',
  632. ['city', 'power'],
  633. false, -1, 1,
  634. 1,
  635. [{res:'electricity',cost:1}],
  636. []);
  637. buildings['city-rock_quarry'] = new PoweredBuilding('city-rock_quarry',
  638. ['city', 'power'],
  639. false, -1, 1,
  640. 1,
  641. [{res:'electricity',cost:1}],
  642. []);
  643. buildings['city-cement_plant'] = new PoweredBuilding('city-cement_plant',
  644. ['city', 'power'],
  645. false, -1, 5,
  646. 3,
  647. [{res:'electricity',cost:2}],
  648. []);
  649. buildings['city-foundry'] = new Building('city-foundry',
  650. ['city'],
  651. false, -1, 5);
  652. buildings['city-factory'] = new PoweredBuilding('city-factory',
  653. ['city', 'power'],
  654. false, -1, 1,
  655. 9,
  656. [{res:'electricity',cost:3}],
  657. []);
  658. buildings['city-smelter'] = new Building('city-smelter',
  659. ['city'],
  660. false, -1, 1);
  661. buildings['city-metal_refinery'] = new Building('city-metal_refinery',
  662. ['city'],
  663. false, -1, 1);
  664. buildings['city-mine'] = new PoweredBuilding('city-mine',
  665. ['city', 'power'],
  666. false, -1, 1,
  667. 2,
  668. [{res:'electricity',cost:1}],
  669. []);
  670. buildings['city-coal_mine'] = new PoweredBuilding('city-coal_mine',
  671. ['city', 'power'],
  672. false, -1, 1,
  673. 2,
  674. [{res:'electricity',cost:1}],
  675. []);
  676. buildings['city-oil_well'] = new Building('city-oil_well',
  677. ['city'],
  678. false, -1, 6);
  679. buildings['city-oil_depot'] = new Building('city-oil_depot',
  680. ['city'],
  681. false, -1, 2);
  682. buildings['city-trade'] = new Building('city-trade',
  683. ['city'],
  684. false, -1, 3);
  685. buildings['city-wharf'] = new Building('city-wharf',
  686. ['city'],
  687. false, -1, 1);
  688. buildings['city-tourist_center'] = new PoweredBuilding('city-tourist_center',
  689. ['city', 'power'],
  690. false, -1, 0,
  691. 9,
  692. [{res:resources.Food,cost:50}],
  693. []);
  694. buildings['city-amphitheatre'] = new Building('city-amphitheatre',
  695. ['city'],
  696. false, -1, 6);
  697. buildings['city-casino'] = new PoweredBuilding('city-casino',
  698. ['city'],
  699. false, -1, 0,
  700. 9,
  701. [{res:'electricity',cost:5}],
  702. []);
  703. buildings['city-temple'] = new Building('city-temple',
  704. ['city'],
  705. false, -1, 5);
  706. buildings['city-university'] = new Building('city-university',
  707. ['city', 'knowledge'],
  708. false, -1, 8);
  709. buildings['city-library'] = new Building('city-library',
  710. ['city', 'knowledge'],
  711. false, -1, 2);
  712. buildings['city-wardenclyffe'] = new PoweredBuilding('city-wardenclyffe',
  713. ['city', 'power', 'knowledge'],
  714. false, -1, 9,
  715. 9,
  716. [{res:'electricity',cost:2}],
  717. []);
  718. buildings['city-biolab'] = new PoweredBuilding('city-biolab',
  719. ['city', 'power', 'knowledge'],
  720. false, -1, 6,
  721. 9,
  722. [{res:'electricity',cost:2}],
  723. []);
  724. buildings['city-coal_power'] = new PoweredBuilding('city-coal_power',
  725. ['city', 'power'],
  726. false, -1, 4,
  727. 9,
  728. [{res:resources.Coal,cost:0.35}],
  729. [{res:'electricity',cost:5}]);
  730. buildings['city-oil_power'] = new PoweredBuilding('city-oil_power',
  731. ['city', 'power'],
  732. false, -1, 4,
  733. 9,
  734. [{res:resources.Oil,cost:0.65}],
  735. [{res:'electricity',cost:6}]);
  736. buildings['city-fission_power'] = new PoweredBuilding('city-fission_power',
  737. ['city', 'power'],
  738. false, -1, 5,
  739. 9,
  740. [{res:resources.Uranium,cost:0.1}],
  741. [{res:'electricity',cost:14}]);
  742. buildings['city-mass_driver'] = new PoweredBuilding('city-mass_driver',
  743. ['city', 'power'],
  744. false, -1, 1,
  745. 9,
  746. [{res:'electricity',cost:5}],
  747. []);
  748. buildings['space-test_launch'] = new Building('space-test_launch',
  749. ['space', 'home', 'mission'],
  750. false, -1, 10);
  751. buildings['space-satellite'] = new Building('space-satellite',
  752. ['space', 'home', 'knowledge'],
  753. false, -1, 1);
  754. buildings['space-gps'] = new Building('space-gps',
  755. ['space', 'home', 'trade'],
  756. false, -1, 0);
  757. buildings['space-propellant_depot'] = new Building('space-propellant_depot',
  758. ['space', 'home', 'storage'],
  759. false, -1, 1);
  760. buildings['space-nav_beacon'] = new PoweredBuilding('space-nav_beacon',
  761. ['space', 'home', 'power'],
  762. false, -1, 2,
  763. 9,
  764. [{res:'electricity',cost:2}],
  765. [{res:'moon_support',cost:1}]);
  766. buildings['space-moon_mission'] = new Building('space-moon_mission',
  767. ['space', 'moon', 'mission'],
  768. false, -1, 10);
  769. buildings['space-moon_base'] = new PoweredBuilding('space-moon_base',
  770. ['space', 'moon', 'power'],
  771. false, -1, 2,
  772. 9,
  773. [],
  774. [{res:'moon_support',cost:2}]);
  775. buildings['space-iridium_mine'] = new PoweredBuilding('space-iridium_mine',
  776. ['space', 'moon', 'power'],
  777. false, -1, 3,
  778. 9,
  779. [{res:'moon_support',cost:1}],
  780. []);
  781. buildings['space-helium_mine'] = new PoweredBuilding('space-helium_mine',
  782. ['space', 'moon', 'power'],
  783. false, -1, 1,
  784. 9,
  785. [{res:'moon_support',cost:1}],
  786. []);
  787. buildings['space-observatory'] = new PoweredBuilding('space-observatory',
  788. ['space', 'moon', 'knowledge', 'power'],
  789. false, -1, 2,
  790. 9,
  791. [{res:'moon_support',cost:1}],
  792. []);
  793. buildings['space-red_mission'] = new Building('space-red_mission',
  794. ['space', 'red', 'mission'],
  795. false, -1, 10);
  796. buildings['space-spaceport'] = new PoweredBuilding('space-spaceport',
  797. ['space', 'red', 'power'],
  798. false, -1, 1,
  799. 9,
  800. [],
  801. [{res:'red_support',cost:3}]);
  802. buildings['space-red_tower'] = new PoweredBuilding('space-red_tower',
  803. ['space', 'red', 'power'],
  804. false, -1, 1,
  805. 9,
  806. [{res:'red_support',cost:1}],
  807. []);
  808. buildings['space-living_quarters'] = new PoweredBuilding('space-living_quarters',
  809. ['space', 'red', 'citizen', 'power'],
  810. false, -1, 1,
  811. 9,
  812. [{res:'red_support',cost:1}],
  813. []);
  814. buildings['space-garage'] = new Building('space-garage',
  815. ['space', 'red', 'storage'],
  816. false, -1, 1);
  817. buildings['space-red_mine'] = new PoweredBuilding('space-red_mine',
  818. ['space', 'red', 'power'],
  819. false, -1, 1,
  820. 9,
  821. [{res:'red_support',cost:1}],
  822. []);
  823. buildings['space-fabrication'] = new PoweredBuilding('space-fabrication',
  824. ['space', 'red', 'power'],
  825. false, -1, 1,
  826. 9,
  827. [{res:'red_support',cost:1}],
  828. []);
  829. buildings['space-red_factory'] = new PoweredBuilding('space-red_factory',
  830. ['space', 'red', 'power'],
  831. false, -1, 1,
  832. 9,
  833. [{res:'electricity',cost:3}],
  834. []);
  835. buildings['space-biodome'] = new PoweredBuilding('space-biodome',
  836. ['space', 'red', 'food', 'power'],
  837. false, -1, 0,
  838. 9,
  839. [{res:'red_support',cost:1}],
  840. []);
  841. buildings['space-exotic_lab'] = new PoweredBuilding('space-exotic_lab',
  842. ['space', 'red', 'knowledge', 'power'],
  843. false, -1, 0,
  844. 9,
  845. [{res:'red_support',cost:1}],
  846. []);
  847. buildings['space-ziggurat'] = new Building('space-ziggurat',
  848. ['space', 'red'],
  849. false, -1, 3);
  850. buildings['space-space_barracks'] = new Building('space-space_barracks',
  851. ['space', 'red', 'army'],
  852. false, -1, 0);
  853. buildings['space-hell_mission'] = new Building('space-hell_mission',
  854. ['space', 'hell', 'mission'],
  855. false, -1, 10);
  856. buildings['space-geothermal'] = new PoweredBuilding('space-geothermal',
  857. ['space', 'hell', 'power'],
  858. false, -1, 0,
  859. 9,
  860. [],
  861. []);
  862. buildings['space-swarm_plant'] = new Building('space-swarm_plant',
  863. ['space', 'hell'],
  864. false, -1, 0);
  865. buildings['space-sun_mission'] = new Building('space-sun_mission',
  866. ['space', 'sun', 'mission'],
  867. false, -1, 10);
  868. buildings['space-swarm_control'] = new PoweredBuilding('space-swarm_control',
  869. ['space', 'sun', 'power'],
  870. false, -1, 1,
  871. 9,
  872. [],
  873. []);
  874. buildings['space-swarm_satellite'] = new PoweredBuilding('space-swarm_satellite',
  875. ['space', 'sun', 'power'],
  876. false, -1, 3,
  877. 9,
  878. [],
  879. []);
  880. buildings['space-gas_mission'] = new Building('space-gas_mission',
  881. ['space', 'gas', 'mission'],
  882. false, -1, 10);
  883. buildings['space-gas_mining'] = new PoweredBuilding('space-gas_mining',
  884. ['space', 'gas', 'power'],
  885. false, -1, 4,
  886. 9,
  887. [],
  888. []);
  889. buildings['space-gas_storage'] = new Building('space-gas_storage',
  890. ['space', 'gas', 'storage'],
  891. false, -1, 2);
  892. buildings['space-star_dock'] = new Building('space-star_dock',
  893. ['space', 'gas'],
  894. false, 1, 6);
  895. buildings['space-gas_moon_mission'] = new Building('space-gas_moon_mission',
  896. ['space', 'gas_moon', 'mission'],
  897. false, -1, 10);
  898. buildings['space-outpost'] = new PoweredBuilding('space-outpost',
  899. ['space', 'gas_moon', 'power'],
  900. false, -1, 1,
  901. 9,
  902. [],
  903. []);
  904. buildings['space-drone'] = new Building('space-drone',
  905. ['space', 'gas_moon'],
  906. false, -1, 0);
  907. buildings['space-oil_extractor'] = new PoweredBuilding('space-oil_extractor',
  908. ['space', 'gas_moon', 'power'],
  909. false, -1, 0,
  910. 9,
  911. [],
  912. []);
  913. buildings['space-belt_mission'] = new Building('space-belt_mission',
  914. ['space', 'belt', 'mission'],
  915. false, -1, 10);
  916. buildings['space-space_station'] = new PoweredBuilding('space-space_station',
  917. ['space', 'belt', 'power'],
  918. false, -1, 1,
  919. 9,
  920. [],
  921. []);
  922. buildings['space-elerium_ship'] = new PoweredBuilding('space-elerium_ship',
  923. ['space', 'belt', 'power'],
  924. false, -1, 1,
  925. 9,
  926. [],
  927. []);
  928. buildings['space-iridium_ship'] = new PoweredBuilding('space-iridium_ship',
  929. ['space', 'belt', 'power'],
  930. false, -1, 2,
  931. 9,
  932. [],
  933. []);
  934. buildings['space-iron_ship'] = new PoweredBuilding('space-iron_ship',
  935. ['space', 'belt', 'power'],
  936. false, -1, 0,
  937. 9,
  938. [],
  939. []);
  940. buildings['space-dwarf_mission'] = new Building('space-dwarf_mission',
  941. ['space', 'dwarf', 'mission'],
  942. false, -1, 10);
  943. buildings['space-elerium_contain'] = new Building('space-elerium_contain',
  944. ['space', 'dwarf', 'storage'],
  945. false, -1, 1);
  946. buildings['space-e_reactor'] = new PoweredBuilding('space-e_reactor',
  947. ['space', 'dwarf', 'power'],
  948. false, -1, 0,
  949. 9,
  950. [],
  951. []);
  952. buildings['space-world_collider'] = new Building('space-world_collider',
  953. ['space', 'dwarf'],
  954. false, 1859, 0);
  955. buildings['space-world_controller'] = new PoweredBuilding('space-world_controller',
  956. ['space', 'dwarf', 'power'],
  957. false, 1, 0,
  958. 9,
  959. [{res:'electricity',cost:20}],
  960. []);
  961. buildings['space-vr_center'] = new Building('space-vr_center',
  962. [],
  963. false, -1, 0);
  964. buildings['interstellar-starport'] = new PoweredBuilding('interstellar-starport',
  965. ['interstellar', 'starport'],
  966. false, -1, 0,
  967. 9,
  968. [{res:'electricity',cost:10}],
  969. []);
  970. buildings['interstellar-warehouse'] = new Building('interstellar-warehouse',
  971. [],
  972. false, -1, 0);
  973. buildings['interstellar-mining_droid'] = new Building('interstellar-mining_droid',
  974. [],
  975. false, -1, 0);
  976. buildings['interstellar-habitat'] = new PoweredBuilding('interstellar-habitat',
  977. [],
  978. false, -1, 0,
  979. 9,
  980. [{res:'electricity',cost:2}],
  981. []);
  982. buildings['interstellar-laboratory'] = new Building('interstellar-laboratory',
  983. [],
  984. false, -1, 0);
  985. buildings['interstellar-exchange'] = new Building('interstellar-exchange',
  986. [],
  987. false, -1, 0);
  988. buildings['interstellar-xfer_station'] = new PoweredBuilding('interstellar-xfer_station',
  989. [],
  990. false, -1, 0,
  991. 9,
  992. [{res:'electricity',cost:1}],
  993. []);
  994.  
  995. buildings['interstellar-cargo_yard'] = new Building('interstellar-cargo_yard',
  996. [],
  997. false, -1, 0);
  998. buildings['interstellar-dyson'] = new Building('interstellar-dyson',
  999. ['interstellar', 'dyson'],
  1000. false, 100, 0);
  1001. buildings['interstellar-processing'] = new PoweredBuilding('interstellar-processing',
  1002. ['interstellar', 'processing'],
  1003. false, -1, 0,
  1004. 9,
  1005. [{res:'int_alpha',cost:1}],
  1006. []);
  1007. buildings['interstellar-stellar_engine'] = new Building('interstellar-stellar_engine',
  1008. ['interstellar', 'stellar_engine'],
  1009. false, 100, 0);
  1010. buildings['interstellar-proxima_mission'] = new Building('interstellar-proxima_mission',
  1011. [],
  1012. false, -1, 0);
  1013. buildings['interstellar-nebula_mission'] = new Building('interstellar-nebula_mission',
  1014. [],
  1015. false, -1, 0);
  1016. buildings['interstellar-harvester'] = new Building('interstellar-harvester',
  1017. [],
  1018. false, -1, 0);
  1019. buildings['interstellar-g_factory'] = new Building('interstellar-g_factory',
  1020. [],
  1021. false, -1, 0);
  1022. buildings['interstellar-fusion'] = new Building('interstellar-fusion',
  1023. [],
  1024. false, -1, 0);
  1025. buildings['interstellar-nexus'] = new PoweredBuilding('interstellar-nexus',
  1026. [],
  1027. false, -1, 0,
  1028. 9,
  1029. [{res:'electricity', cost:8}],
  1030. []);
  1031. buildings['interstellar-neutron_mission'] = new Building('interstellar-neutron_mission',
  1032. [],
  1033. false, -1, 0);
  1034. buildings['interstellar-blackhole_mission'] = new Building('interstellar-blackhole_mission',
  1035. [],
  1036. false, -1, 0);
  1037. buildings['interstellar-cruiser'] = new Building('interstellar-cruiser',
  1038. [],
  1039. false, -1, 0);
  1040.  
  1041. buildings['interstellar-far_reach'] = new PoweredBuilding('interstellar-far_reach',
  1042. [],
  1043. false, -1, 0,
  1044. 9,
  1045. [{res:'electricity',cost:5}],
  1046. []);
  1047. buildings['interstellar-elerium_prospector'] = new Building('interstellar-elerium_prospector',
  1048. [],
  1049. false, -1, 0);
  1050. buildings['interstellar-mass_ejector'] = new PoweredBuilding('interstellar-mass_ejector',
  1051. [],
  1052. false, -1, 0,
  1053. 9,
  1054. [{res:'electricity',cost:2}],
  1055. []);
  1056. buildings['portal-turret'] = new PoweredBuilding('portal-turret',
  1057. ['portal', 'turret', 'power'],
  1058. false, -1, 0,
  1059. 9,
  1060. [{res:'electricity',cost:5}],
  1061. []);
  1062. buildings['portal-carport'] = new PoweredBuilding('portal-carport',
  1063. [],
  1064. false, -1, 0,
  1065. 9,
  1066. [{}],
  1067. []);
  1068. buildings['portal-sensor_drone'] = new PoweredBuilding('portal-sensor_drone',
  1069. ['portal', 'sensor_drone', 'power'],
  1070. false, -1, 0,
  1071. 9,
  1072. [{res:'electricity',cost:3}],
  1073. []);
  1074. buildings['portal-attractor'] = new PoweredBuilding('portal-attractor',
  1075. [],
  1076. false, -1, 0,
  1077. 9,
  1078. [{res:'electricity',cost:3}],
  1079. []);
  1080. }
  1081.  
  1082. class Research extends Action {
  1083. constructor(id, tags, priority) {
  1084. super(id, tags, priority);
  1085. this.done = false;
  1086. }
  1087.  
  1088. get researched() {
  1089. if (this.done) {
  1090. return true;
  1091. }
  1092.  
  1093. let researched = $('#oldTech > div');
  1094. for (let i = 0;i < researched.length;i++) {
  1095. if (this.id == researched[i].id) {
  1096. this.done = true;
  1097. return true;
  1098. }
  1099. }
  1100. return false;
  1101. }
  1102.  
  1103. }
  1104. var researches = [];
  1105. function loadResearches() {
  1106. if (!settings.hasOwnProperty('actions')) {settings.actions = {};}
  1107. researches['tech-club'] = new Research('tech-club',
  1108. ['food'],
  1109. 1);
  1110. researches['tech-bone_tools'] = new Research('tech-bone_tools',
  1111. ['stone'],
  1112. 1);
  1113. researches['tech-sundial'] = new Research('tech-sundial',
  1114. ['knowledge'],
  1115. 5);
  1116. researches['tech-housing'] = new Research('tech-housing',
  1117. ['citizen'],
  1118. 5);
  1119. researches['tech-cottage'] = new Research('tech-cottage',
  1120. ['citizen'],
  1121. 0);
  1122. researches['tech-apartment'] = new Research('tech-apartment',
  1123. ['citzen', 'power'],
  1124. 5);
  1125. researches['tech-steel_beams'] = new Research('tech-steel_beams',
  1126. ['citizen'],
  1127. 1);
  1128. researches['tech-mythril_beams'] = new Research('tech-mythril_beams',
  1129. ['citizen'],
  1130. 1);
  1131. researches['tech-neutronium_walls'] = new Research('tech-neutronium_walls',
  1132. ['citizen'],
  1133. 1);
  1134. researches['tech-aphrodisiac'] = new Research('tech-aphrodisiac',
  1135. ['citizen'],
  1136. 0);
  1137. researches['tech-smokehouse'] = new Research('tech-smokehouse',
  1138. ['food'],
  1139. 1);
  1140. researches['tech-lodge'] = new Research('tech-lodge',
  1141. ['citizen'],
  1142. 1);
  1143. researches['tech-soul_well'] = new Research('tech-soul_well',
  1144. [],
  1145. 1);
  1146. researches['tech-agriculture'] = new Research('tech-agriculture',
  1147. ['food'],
  1148. 0);
  1149. researches['tech-farm_house'] = new Research('tech-farm_house',
  1150. ['food', 'citizen'],
  1151. 5);
  1152. researches['tech-irrigation'] = new Research('tech-irrigation',
  1153. ['food'],
  1154. 1);
  1155. researches['tech-silo'] = new Research('tech-silo',
  1156. ['food'],
  1157. 0);
  1158. researches['tech-mill'] = new Research('tech-mill',
  1159. ['food'],
  1160. 1);
  1161. researches['tech-windmill'] = new Research('tech-windmill',
  1162. ['food'],
  1163. 1);
  1164. researches['tech-windturbine'] = new Research('tech-windturbine',
  1165. ['food', 'power'],
  1166. 5);
  1167. researches['tech-wind_plant'] = new Research('tech-wind_plant',
  1168. ['food'],
  1169. 1);
  1170. researches['tech-evil_wind_plant'] = new Research('tech-evil_wind_plant',
  1171. [],
  1172. 0);
  1173. researches['tech-gmfood'] = new Research('tech-gmfood',
  1174. ['food'],
  1175. 0);
  1176. researches['tech-foundry'] = new Research('tech-foundry',
  1177. ['craft'],
  1178. 7);
  1179. researches['tech-artisans'] = new Research('tech-artisans',
  1180. ['craft'],
  1181. 4);
  1182. researches['tech-apprentices'] = new Research('tech-apprentices',
  1183. ['craft'],
  1184. 4);
  1185. researches['tech-carpentry'] = new Research('tech-carpentry',
  1186. ['craft'],
  1187. 4);
  1188. researches['tech-demonic_craftsman'] = new Research('tech-demonic_craftsman',
  1189. ['craft'],
  1190. 4);
  1191. researches['tech-master_craftsman'] = new Research('tech-master_craftsman',
  1192. ['craft'],
  1193. 4);
  1194. researches['tech-brickworks'] = new Research('tech-brickworks',
  1195. ['craft'],
  1196. 4);
  1197. researches['tech-machinery'] = new Research('tech-machinery',
  1198. ['factory'],
  1199. 4);
  1200. researches['tech-cnc_machine'] = new Research('tech-cnc_machine',
  1201. ['craft'],
  1202. 4);
  1203. researches['tech-vocational_training'] = new Research('tech-vocational_training',
  1204. ['craft'],
  1205. 4);
  1206. researches['tech-assembly_line'] = new Research('tech-assembly_line',
  1207. ['factory'],
  1208. 4);
  1209. researches['tech-automation'] = new Research('tech-automation',
  1210. ['factory'],
  1211. 4);
  1212. researches['tech-laser_cutters'] = new Research('tech-laser_cutters',
  1213. ['craft'],
  1214. 3);
  1215. researches['tech-theatre'] = new Research('tech-theatre',
  1216. ['morale'],
  1217. 7);
  1218. researches['tech-playwright'] = new Research('tech-playwright',
  1219. ['morale'],
  1220. 6);
  1221. researches['tech-magic'] = new Research('tech-magic',
  1222. ['morale'],
  1223. 7);
  1224. researches['tech-radio'] = new Research('tech-radio',
  1225. ['morale'],
  1226. 7);
  1227. researches['tech-tv'] = new Research('tech-tv',
  1228. ['morale'],
  1229. 7);
  1230. researches['tech-casino'] = new Research('tech-casino',
  1231. ['casino', 'power'],
  1232. 0);
  1233. researches['tech-dazzle'] = new Research('tech-dazzle',
  1234. ['casino'],
  1235. 0);
  1236. researches['tech-casino_vault'] = new Research('tech-casino_vault',
  1237. ['casino'],
  1238. 0);
  1239. researches['tech-mining'] = new Research('tech-mining',
  1240. ['mine'],
  1241. 7);
  1242. researches['tech-bayer_process'] = new Research('tech-bayer_process',
  1243. ['aluminum'],
  1244. 10);
  1245. researches['tech-smelting'] = new Research('tech-smelting',
  1246. ['mine'],
  1247. 2);
  1248. researches['tech-steel'] = new Research('tech-steel',
  1249. ['smelter', 'steel'],
  1250. 8);
  1251. researches['tech-blast_furnace'] = new Research('tech-blast_furnace',
  1252. ['smelter', 'iron'],
  1253. 2);
  1254. researches['tech-bessemer_process'] = new Research('tech-bessemer_process',
  1255. ['smelter', 'steel'],
  1256. 2);
  1257. researches['tech-oxygen_converter'] = new Research('tech-oxygen_converter',
  1258. ['smelter', 'steel'],
  1259. 2);
  1260. researches['tech-electric_arc_furnace'] = new Research('tech-electric_arc_furnace',
  1261. ['copper'],
  1262. 2);
  1263. researches['tech-rotary_kiln'] = new Research('tech-rotary_kiln',
  1264. ['copper'],
  1265. 2);
  1266. researches['tech-metal_working'] = new Research('tech-metal_working',
  1267. ['copper'],
  1268. 7);
  1269. researches['tech-iron_mining'] = new Research('tech-iron_mining',
  1270. ['iron'],
  1271. 7);
  1272. researches['tech-coal_mining'] = new Research('tech-coal_mining',
  1273. ['coal'],
  1274. 7);
  1275. researches['tech-storage'] = new Research('tech-storage',
  1276. ['storage'],
  1277. 5);
  1278. researches['tech-reinforced_shed'] = new Research('tech-reinforced_shed',
  1279. ['storage'],
  1280. 5);
  1281. researches['tech-barns'] = new Research('tech-barns',
  1282. ['storage'],
  1283. 5);
  1284. researches['tech-warehouse'] = new Research('tech-warehouse',
  1285. ['storage'],
  1286. 5);
  1287. researches['tech-cameras'] = new Research('tech-cameras',
  1288. ['storage'],
  1289. 5);
  1290. researches['tech-pocket_dimensions'] = new Research('tech-pocket_dimensions',
  1291. ['storage'],
  1292. 5);
  1293. researches['tech-containerization'] = new Research('tech-containerization',
  1294. ['storage', 'crate'],
  1295. 5);
  1296. researches['tech-reinforced_crates'] = new Research('tech-reinforced_crates',
  1297. ['storage', 'crate'],
  1298. 5);
  1299. researches['tech-cranes'] = new Research('tech-cranes',
  1300. ['storage', 'crate'],
  1301. 5);
  1302. researches['tech-titanium_crates'] = new Research('tech-titanium_crates',
  1303. ['storage', 'crate'],
  1304. 5);
  1305. researches['tech-mythril_crates'] = new Research('tech-mythril_crates',
  1306. ['storage', 'crate'],
  1307. 5);
  1308. researches['tech-steel_containers'] = new Research('tech-steel_containers',
  1309. ['storage', 'container'],
  1310. 5);
  1311. researches['tech-gantry_crane'] = new Research('tech-gantry_crane',
  1312. ['storage', 'container'],
  1313. 5);
  1314. researches['tech-alloy_containers'] = new Research('tech-alloy_containers',
  1315. ['storage', 'container'],
  1316. 5);
  1317. researches['tech-mythril_containers'] = new Research('tech-mythril_containers',
  1318. ['storage', 'container'],
  1319. 5);
  1320. researches['tech-currency'] = new Research('tech-currency',
  1321. ['money'],
  1322. 10);
  1323. researches['tech-market'] = new Research('tech-market',
  1324. ['money', 'market'],
  1325. 3);
  1326. researches['tech-tax_rates'] = new Research('tech-tax_rates',
  1327. ['money', 'tax'],
  1328. 1);
  1329. researches['tech-large_trades'] = new Research('tech-large_trades',
  1330. ['money', 'market'],
  1331. 0);
  1332. researches['tech-corruption'] = new Research('tech-corruption',
  1333. ['money', 'tax'],
  1334. 1);
  1335. researches['tech-massive_trades'] = new Research('tech-massive_trades',
  1336. ['money', 'market'],
  1337. 0);
  1338. researches['tech-trade'] = new Research('tech-trade',
  1339. ['trade'],
  1340. 7);
  1341. researches['tech-diplomacy'] = new Research('tech-diplomacy',
  1342. ['trade'],
  1343. 3);
  1344. researches['tech-freight'] = new Research('tech-freight',
  1345. ['trade'],
  1346. 3);
  1347. researches['tech-wharf'] = new Research('tech-wharf',
  1348. ['trade', 'storage', 'crate', 'container'],
  1349. 1);
  1350. researches['tech-banking'] = new Research('tech-banking',
  1351. ['money'],
  1352. 1);
  1353. researches['tech-investing'] = new Research('tech-investing',
  1354. ['money'],
  1355. 5);
  1356. researches['tech-vault'] = new Research('tech-vault',
  1357. ['money'],
  1358. 2);
  1359. researches['tech-bonds'] = new Research('tech-bonds',
  1360. ['money'],
  1361. 0);
  1362. researches['tech-steel_vault'] = new Research('tech-steel_vault',
  1363. ['money'],
  1364. 0);
  1365. researches['tech-eebonds'] = new Research('tech-eebonds',
  1366. ['money'],
  1367. 0);
  1368. researches['tech-swiss_banking'] = new Research('tech-swiss_banking',
  1369. ['money'],
  1370. 0);
  1371. researches['tech-safety_deposit'] = new Research('tech-safety_deposit',
  1372. ['money'],
  1373. 0);
  1374. researches['tech-stock_market'] = new Research('tech-stock_market',
  1375. ['money'],
  1376. 0);
  1377. researches['tech-hedge_funds'] = new Research('tech-hedge_funds',
  1378. ['money'],
  1379. 0);
  1380. researches['tech-four_oh_one'] = new Research('tech-four_oh_one',
  1381. ['money'],
  1382. 0);
  1383. researches['tech-mythril_vault'] = new Research('tech-mythril_vault',
  1384. ['money'],
  1385. 0);
  1386. researches['tech-neutronium_vault'] = new Research('tech-neutronium_vault',
  1387. ['money'],
  1388. 0);
  1389. researches['tech-home_safe'] = new Research('tech-home_safe',
  1390. ['money'],
  1391. 0);
  1392. researches['tech-fire_proof_safe'] = new Research('tech-fire_proof_safe',
  1393. ['money'],
  1394. 0);
  1395. researches['tech-monument'] = new Research('tech-monument',
  1396. ['morale'],
  1397. 0);
  1398. researches['tech-tourism'] = new Research('tech-tourism',
  1399. ['money'],
  1400. 0);
  1401. researches['tech-science'] = new Research('tech-science',
  1402. ['knowledge'],
  1403. 10);
  1404. researches['tech-library'] = new Research('tech-library',
  1405. ['knowledge'],
  1406. 10);
  1407. researches['tech-thesis'] = new Research('tech-thesis',
  1408. ['knowledge'],
  1409. 9);
  1410. researches['tech-research_grant'] = new Research('tech-research_grant',
  1411. ['knowledge'],
  1412. 9);
  1413. researches['tech-scientific_journal'] = new Research('tech-scientific_journal',
  1414. ['knowledge'],
  1415. 9);
  1416. researches['tech-adjunct_professor'] = new Research('tech-adjunct_professor',
  1417. ['knowledge'],
  1418. 10);
  1419. researches['tech-tesla_coil'] = new Research('tech-tesla_coil',
  1420. ['knowledge'],
  1421. 10);
  1422. researches['tech-internet'] = new Research('tech-internet',
  1423. ['knowledge'],
  1424. 10);
  1425. researches['tech-observatory'] = new Research('tech-observatory',
  1426. ['knowledge'],
  1427. 8);
  1428. researches['tech-world_collider'] = new Research('tech-world_collider',
  1429. [],
  1430. 5);
  1431. researches['tech-bioscience'] = new Research('tech-bioscience',
  1432. ['knowledge'],
  1433. 10);
  1434. researches['tech-genetics'] = new Research('tech-genetics',
  1435. ['gene'],
  1436. 0);
  1437. researches['tech-crispr'] = new Research('tech-crispr',
  1438. ['gene'],
  1439. 0);
  1440. researches['tech-shotgun_sequencing'] = new Research('tech-shotgun_sequencing',
  1441. ['gene'],
  1442. 0);
  1443. researches['tech-de_novo_sequencing'] = new Research('tech-de_novo_sequencing',
  1444. ['gene'],
  1445. 0);
  1446. researches['tech-dna_sequencer'] = new Research('tech-dna_sequencer',
  1447. ['gene'],
  1448. 0);
  1449. researches['tech-mad_science'] = new Research('tech-mad_science',
  1450. ['knowledge'],
  1451. 10);
  1452. researches['tech-electricity'] = new Research('tech-electricity',
  1453. ['power'],
  1454. 9);
  1455. researches['tech-industrialization'] = new Research('tech-industrialization',
  1456. [],
  1457. 9);
  1458. researches['tech-electronics'] = new Research('tech-electronics',
  1459. ['power'],
  1460. 9);
  1461. researches['tech-fission'] = new Research('tech-fission',
  1462. ['power', 'uranium'],
  1463. 7);
  1464. researches['tech-arpa'] = new Research('tech-arpa',
  1465. [],
  1466. 5);
  1467. researches['tech-rocketry'] = new Research('tech-rocketry',
  1468. [],
  1469. 9);
  1470. researches['tech-robotics'] = new Research('tech-robotics',
  1471. [],
  1472. 9);
  1473. researches['tech-lasers'] = new Research('tech-lasers',
  1474. [],
  1475. 9);
  1476. researches['tech-artifical_intelligence'] = new Research('tech-artifical_intelligence',
  1477. [],
  1478. 9);
  1479. researches['tech-quantum_computing'] = new Research('tech-quantum_computing',
  1480. [],
  1481. 9);
  1482. researches['tech-thermomechanics'] = new Research('tech-thermomechanics',
  1483. ['factory', 'alloy'],
  1484. 5);
  1485. researches['tech-quantum_manufacturing'] = new Research('tech-quantum_manufacturing',
  1486. ['factory'],
  1487. 5);
  1488. researches['tech-worker_drone'] = new Research('tech-worker_drone',
  1489. ['neutronium'],
  1490. 10);
  1491. researches['tech-uranium'] = new Research('tech-uranium',
  1492. ['uranium'],
  1493. 7);
  1494. researches['tech-uranium_storage'] = new Research('tech-uranium_storage',
  1495. ['uranium'],
  1496. 6);
  1497. researches['tech-uranium_ash'] = new Research('tech-uranium_ash',
  1498. ['uranium'],
  1499. 6);
  1500. researches['tech-breeder_reactor'] = new Research('tech-breeder_reactor',
  1501. ['power'],
  1502. 4);
  1503. researches['tech-mine_conveyor'] = new Research('tech-mine_conveyor',
  1504. ['mine', 'power'],
  1505. 4);
  1506. researches['tech-oil_well'] = new Research('tech-oil_well',
  1507. ['oil'],
  1508. 5);
  1509. researches['tech-oil_depot'] = new Research('tech-oil_depot',
  1510. ['oil'],
  1511. 5);
  1512. researches['tech-oil_power'] = new Research('tech-oil_power',
  1513. ['oil', 'power'],
  1514. 7);
  1515. researches['tech-titanium_drills'] = new Research('tech-titanium_drills',
  1516. ['oil'],
  1517. 5);
  1518. researches['tech-alloy_drills'] = new Research('tech-alloy_drills',
  1519. ['oil'],
  1520. 4);
  1521. researches['tech-fracking'] = new Research('tech-fracking',
  1522. ['oil'],
  1523. 4);
  1524. researches['tech-mythril_drills'] = new Research('tech-mythril_drills',
  1525. ['oil'],
  1526. 2);
  1527. researches['tech-mass_driver'] = new Research('tech-mass_driver',
  1528. ['power'],
  1529. 0);
  1530. researches['tech-polymer'] = new Research('tech-polymer',
  1531. ['factory', 'polymer'],
  1532. 10);
  1533. researches['tech-fluidized_bed_reactor'] = new Research('tech-fluidized_bed_reactor',
  1534. ['factory', 'polymer'],
  1535. 4);
  1536. researches['tech-nano_tubes'] = new Research('tech-nano_tubes',
  1537. ['factory', 'nano_tubes'],
  1538. 5);
  1539. researches['tech-stone_axe'] = new Research('tech-stone_axe',
  1540. ['lumber'],
  1541. 1);
  1542. researches['tech-copper_axes'] = new Research('tech-copper_axes',
  1543. ['lumber'],
  1544. 1);
  1545. researches['tech-iron_saw'] = new Research('tech-iron_saw',
  1546. ['lumber'],
  1547. 1);
  1548. researches['tech-steel_saw'] = new Research('tech-steel_saw',
  1549. ['lumber'],
  1550. 1);
  1551. researches['tech-iron_axes'] = new Research('tech-iron_axes',
  1552. ['lumber'],
  1553. 1);
  1554. researches['tech-steel_axes'] = new Research('tech-steel_axes',
  1555. ['lumber'],
  1556. 1);
  1557. researches['tech-titanium_axes'] = new Research('tech-titanium_axes',
  1558. ['lumber'],
  1559. 1);
  1560. researches['tech-copper_sledgehammer'] = new Research('tech-copper_sledgehammer',
  1561. ['stone'],
  1562. 1);
  1563. researches['tech-iron_sledgehammer'] = new Research('tech-iron_sledgehammer',
  1564. ['stone'],
  1565. 1);
  1566. researches['tech-steel_sledgehammer'] = new Research('tech-steel_sledgehammer',
  1567. ['stone'],
  1568. 1);
  1569. researches['tech-titanium_sledgehammer'] = new Research('tech-titanium_sledgehammer',
  1570. ['stone'],
  1571. 1);
  1572. researches['tech-copper_pickaxe'] = new Research('tech-copper_pickaxe',
  1573. ['mine'],
  1574. 2);
  1575. researches['tech-iron_pickaxe'] = new Research('tech-iron_pickaxe',
  1576. ['mine'],
  1577. 2);
  1578. researches['tech-steel_pickaxe'] = new Research('tech-steel_pickaxe',
  1579. ['mine'],
  1580. 2);
  1581. researches['tech-jackhammer'] = new Research('tech-jackhammer',
  1582. ['mine'],
  1583. 2);
  1584. researches['tech-jackhammer_mk2'] = new Research('tech-jackhammer_mk2',
  1585. ['mine'],
  1586. 2);
  1587. researches['tech-copper_hoe'] = new Research('tech-copper_hoe',
  1588. ['food'],
  1589. 2);
  1590. researches['tech-iron_hoe'] = new Research('tech-iron_hoe',
  1591. ['food'],
  1592. 2);
  1593. researches['tech-steel_hoe'] = new Research('tech-steel_hoe',
  1594. ['food'],
  1595. 2);
  1596. researches['tech-titanium_hoe'] = new Research('tech-titanium_hoe',
  1597. ['food'],
  1598. 2);
  1599. researches['tech-slave_pens'] = new Research('tech-slave_pens',
  1600. ['slave'],
  1601. 5);
  1602. researches['tech-garrison'] = new Research('tech-garrison',
  1603. ['army'],
  1604. 9);
  1605. researches['tech-mercs'] = new Research('tech-mercs',
  1606. ['army', 'money'],
  1607. 0);
  1608. researches['tech-signing_bonus'] = new Research('tech-signing_bonus',
  1609. ['army', 'money'],
  1610. 0);
  1611. researches['tech-hospital'] = new Research('tech-hospital',
  1612. ['army'],
  1613. 9);
  1614. researches['tech-boot_camp'] = new Research('tech-boot_camp',
  1615. ['army'],
  1616. 7);
  1617. researches['tech-bows'] = new Research('tech-bows',
  1618. ['army'],
  1619. 2);
  1620. researches['tech-flintlock_rifle'] = new Research('tech-flintlock_rifle',
  1621. ['army'],
  1622. 2);
  1623. researches['tech-machine_gun'] = new Research('tech-machine_gun',
  1624. ['army'],
  1625. 2);
  1626. researches['tech-bunk_beds'] = new Research('tech-bunk_beds',
  1627. ['army'],
  1628. 10);
  1629. researches['tech-rail_guns'] = new Research('tech-rail_guns',
  1630. ['army'],
  1631. 1);
  1632. researches['tech-laser_rifles'] = new Research('tech-laser_rifles',
  1633. ['army'],
  1634. 1);
  1635. researches['tech-space_marines'] = new Research('tech-space_marines',
  1636. ['army'],
  1637. 0);
  1638. researches['tech-armor'] = new Research('tech-armor',
  1639. ['army'],
  1640. 2);
  1641. researches['tech-plate_armor'] = new Research('tech-plate_armor',
  1642. ['army'],
  1643. 2);
  1644. researches['tech-kevlar'] = new Research('tech-kevlar',
  1645. ['army'],
  1646. 2);
  1647. researches['tech-black_powder'] = new Research('tech-black_powder',
  1648. [],
  1649. 0);
  1650. researches['tech-dynamite'] = new Research('tech-dynamite',
  1651. ['mine'],
  1652. 3);
  1653. researches['tech-anfo'] = new Research('tech-anfo',
  1654. ['mine'],
  1655. 3);
  1656. researches['tech-mad'] = new Research('tech-mad',
  1657. [],
  1658. 10);
  1659. researches['tech-cement'] = new Research('tech-cement',
  1660. ['cement'],
  1661. 5);
  1662. researches['tech-rebar'] = new Research('tech-rebar',
  1663. ['cement'],
  1664. 4);
  1665. researches['tech-steel_rebar'] = new Research('tech-steel_rebar',
  1666. ['cement'],
  1667. 4);
  1668. researches['tech-portland_cement'] = new Research('tech-portland_cement',
  1669. ['cement'],
  1670. 4);
  1671. researches['tech-screw_conveyor'] = new Research('tech-screw_conveyor',
  1672. ['cement', 'power'],
  1673. 4);
  1674. researches['tech-hunter_process'] = new Research('tech-hunter_process',
  1675. ['smelter', 'titanium'],
  1676. 9);
  1677. researches['tech-kroll_process'] = new Research('tech-kroll_process',
  1678. ['smelter', 'titanium'],
  1679. 3);
  1680. researches['tech-cambridge_process'] = new Research('tech-cambridge_process',
  1681. ['smelter', 'titanium'],
  1682. 9);
  1683. researches['tech-pynn_partical'] = new Research('tech-pynn_partical',
  1684. ['storage'],
  1685. 8);
  1686. researches['tech-matter_compression'] = new Research('tech-matter_compression',
  1687. ['storage', 'container'],
  1688. 7);
  1689. researches['tech-higgs_boson'] = new Research('tech-higgs_boson',
  1690. ['storage'],
  1691. 7);
  1692. researches['tech-dimensional_compression'] = new Research('tech-dimensional_compression',
  1693. ['storage', 'garage'],
  1694. 5);
  1695. researches['tech-theology'] = new Research('tech-theology',
  1696. ['religion'],
  1697. 4);
  1698. researches['tech-fanaticism'] = new Research('tech-fanaticism',
  1699. ['religion'],
  1700. 4);
  1701. researches['tech-ancient_theology'] = new Research('tech-ancient_theology',
  1702. ['religion'],
  1703. 4);
  1704. researches['tech-study'] = new Research('tech-study',
  1705. ['religion'],
  1706. 4);
  1707. researches['tech-deify'] = new Research('tech-deify',
  1708. ['religion'],
  1709. 4);
  1710. researches['tech-indoctrination'] = new Research('tech-indoctrination',
  1711. ['religion', 'knowledge'],
  1712. 4);
  1713. researches['tech-missionary'] = new Research('tech-missionary',
  1714. ['religion', 'trade'],
  1715. 4);
  1716. researches['tech-zealotry'] = new Research('tech-zealotry',
  1717. ['religion', 'army'],
  1718. 4);
  1719. researches['tech-anthropology'] = new Research('tech-anthropology',
  1720. ['religion'],
  1721. 4);
  1722. researches['tech-mythology'] = new Research('tech-mythology',
  1723. ['religion', 'knowledge'],
  1724. 4);
  1725. researches['tech-archaeology'] = new Research('tech-archaeology',
  1726. ['religion', 'knowledge'],
  1727. 4);
  1728. researches['tech-merchandising'] = new Research('tech-merchandising',
  1729. ['religion', 'money', 'tax'],
  1730. 0);
  1731. researches['tech-astrophysics'] = new Research('tech-astrophysics',
  1732. ['space'],
  1733. 5);
  1734. researches['tech-rover'] = new Research('tech-rover',
  1735. ['space'],
  1736. 10);
  1737. researches['tech-probes'] = new Research('tech-probes',
  1738. ['space'],
  1739. 10);
  1740. researches['tech-starcharts'] = new Research('tech-starcharts',
  1741. ['space'],
  1742. 5);
  1743. researches['tech-colonization'] = new Research('tech-colonization',
  1744. ['space'],
  1745. 10);
  1746. researches['tech-red_tower'] = new Research('tech-red_tower',
  1747. ['space', 'power'],
  1748. 3);
  1749. researches['tech-space_manufacturing'] = new Research('tech-space_manufacturing',
  1750. ['space', 'factory'],
  1751. 3);
  1752. researches['tech-exotic_lab'] = new Research('tech-exotic_lab',
  1753. ['space', 'knowledge', 'power'],
  1754. 0);
  1755. researches['tech-dyson_sphere'] = new Research('tech-dyson_sphere',
  1756. ['space', 'power', 'swarm'],
  1757. 0);
  1758. researches['tech-dyson_swarm'] = new Research('tech-dyson_swarm',
  1759. ['space', 'power', 'swarm'],
  1760. 0);
  1761. researches['tech-swarm_plant'] = new Research('tech-swarm_plant',
  1762. ['space', 'power', 'swarm'],
  1763. 0);
  1764. researches['tech-space_sourced'] = new Research('tech-space_sourced',
  1765. ['space', 'swarm', 'iron'],
  1766. 0);
  1767. researches['tech-swarm_plant_ai'] = new Research('tech-swarm_plant_ai',
  1768. ['space', 'power', 'swarm'],
  1769. 0);
  1770. researches['tech-swarm_control_ai'] = new Research('tech-swarm_control_ai',
  1771. ['space', 'swarm', 'power'],
  1772. 0);
  1773. researches['tech-quantum_swarm'] = new Research('tech-quantum_swarm',
  1774. ['space', 'swarm', 'power'],
  1775. 0);
  1776. researches['tech-gps'] = new Research('tech-gps',
  1777. ['space',' trade'],
  1778. 0);
  1779. researches['tech-nav_beacon'] = new Research('tech-nav_beacon',
  1780. ['space', 'power'],
  1781. 3);
  1782. researches['tech-atmospheric_mining'] = new Research('tech-atmospheric_mining',
  1783. ['space', 'mine', 'helium_3'],
  1784. 7);
  1785. researches['tech-helium_attractor'] = new Research('tech-helium_attractor',
  1786. ['space', 'helium_3'],
  1787. 7);
  1788. researches['tech-zero_g_mining'] = new Research('tech-zero_g_mining',
  1789. ['space', 'mine'],
  1790. 0);
  1791. researches['tech-elerium_mining'] = new Research('tech-elerium_mining',
  1792. ['space', 'elerium'],
  1793. 10);
  1794. researches['tech-laser_mining'] = new Research('tech-laser_mining',
  1795. ['space', 'mine'],
  1796. 4);
  1797. researches['tech-elerium_tech'] = new Research('tech-elerium_tech',
  1798. ['space', 'elerium'],
  1799. 10);
  1800. researches['tech-elerium_reactor'] = new Research('tech-elerium_reactor',
  1801. ['space', 'elerium', 'power'],
  1802. 0);
  1803. researches['tech-neutronium_housing'] = new Research('tech-neutronium_housing',
  1804. ['space', 'citizen'],
  1805. 0);
  1806. researches['tech-unification'] = new Research('tech-unification',
  1807. ['unification'],
  1808. 10);
  1809. researches['tech-wc_conquest'] = new Research('tech-wc_conquest',
  1810. ['unification'],
  1811. 10);
  1812. researches['tech-wc_morale'] = new Research('tech-wc_morale',
  1813. ['unification'],
  1814. 10);
  1815. researches['tech-wc_money'] = new Research('tech-wc_money',
  1816. ['unification'],
  1817. 10);
  1818. researches['tech-wc_reject'] = new Research('tech-wc_reject',
  1819. ['unification'],
  1820. 10);
  1821. researches['tech-genesis'] = new Research('tech-genesis',
  1822. ['space'],
  1823. 10);
  1824. researches['tech-star_dock'] = new Research('tech-star_dock',
  1825. ['space'],
  1826. 10);
  1827. researches['tech-interstellar'] = new Research('tech-interstellar',
  1828. ['space'],
  1829. 5);
  1830. researches['tech-genesis_ship'] = new Research('tech-genesis_ship',
  1831. ['space'],
  1832. 10);
  1833. researches['tech-genetic_decay'] = new Research('tech-genetic_decay',
  1834. ['gene'],
  1835. 10);
  1836. }
  1837.  
  1838. class ArpaAction extends Action {
  1839. constructor(id, tags, priority, res) {
  1840. super(id, tags, priority);
  1841. this.res = res;
  1842. }
  1843.  
  1844. get unlocked() {
  1845. try {
  1846. let btn = document.querySelector('#arpa'+this.id+' > div.buy > button.button.x10');
  1847. return (btn !== null);
  1848. } catch(e) {
  1849. console.log("Error:", this.id, "Unlocked");
  1850. return false;
  1851. }
  1852. }
  1853.  
  1854. get enabled() {
  1855. return settings.arpa[this.id];
  1856. }
  1857.  
  1858. get rank() {
  1859. try {
  1860. let rankLabel = document.querySelector('#arpa'+this.id+' > .head > .rank');
  1861. let rankStr = rankLabel.innerText;
  1862. let reg = /Level - ([\d]+)/.exec(rankStr);
  1863. return parseInt(reg[1]);
  1864. } catch(e) {
  1865. console.log("Error:", this.id, "Rank");
  1866. return null;
  1867. }
  1868. }
  1869.  
  1870. getResDep(resid) {
  1871. if (this.res === null) {
  1872. return null;
  1873. }
  1874. return this.res[resid.toLowerCase()] * (1.05 ** this.rank) / 10;
  1875. }
  1876.  
  1877. click() {
  1878. try {
  1879. let btn = document.querySelector('#arpa'+this.id+' > div.buy > button.button.x10');
  1880. btn.click();
  1881. return true;
  1882. } catch(e) {
  1883. console.log("Error:", this.id, "Click");
  1884. return false;
  1885. }
  1886. }
  1887.  
  1888. }
  1889. var arpas = {};
  1890. function loadArpas() {
  1891. if (!settings.hasOwnProperty('actions')) {settings.actions = {};}
  1892. arpas.lhc = new ArpaAction('lhc',
  1893. ['arpa'],
  1894. 5,
  1895. {money:2500000,
  1896. knowledge:500000,
  1897. copper:125000,
  1898. cement:250000,
  1899. steel:187500,
  1900. titanium:50000,
  1901. polymer:12000});
  1902. arpas.stock_exchange = new ArpaAction('stock_exchange',
  1903. ['arpa'],
  1904. 5,
  1905. {money:3000000,
  1906. plywood:25000,
  1907. brick:20000,
  1908. wrought_Iron:10000});
  1909. arpas.launch_facility = new ArpaAction('launch_facility',
  1910. ['arpa'],
  1911. 10,
  1912. {money:2000000,
  1913. knowledge:500000,
  1914. cement:150000,
  1915. oil:20000,
  1916. sheet_metal:15000,
  1917. alloy:25000});
  1918. arpas.monument = new ArpaAction('monument', ['arpa'], 5);
  1919. let type = null;
  1920. try {
  1921. type = $('#arpamonument > .head > .desc')[0].innerText;
  1922. } catch(e) {
  1923. //console.log("Error: could not load Monument");
  1924. }
  1925. if (type !== null) {
  1926. switch(type) {
  1927. case "Obelisk":
  1928. {
  1929. arpas.monument.res = {stone:1000000};
  1930. break;
  1931. }
  1932. case "Statue":
  1933. {
  1934. arpas.monument.res = {aluminium:350000};
  1935. break;
  1936. }
  1937. case "Sculpture":
  1938. {
  1939. arpas.monument.res = {steel:300000};
  1940. break;
  1941. }
  1942. case "Monolith":
  1943. {
  1944. arpas.monument.res = {cement:300000};
  1945. break;
  1946. }
  1947. }
  1948. }
  1949. }
  1950.  
  1951. class StorageAction extends Action {
  1952. constructor(id, tags, priority, res) {
  1953. super(id, tags, priority);
  1954. this.res = res;
  1955. }
  1956.  
  1957. get unlocked() {
  1958. if (this.id == 'crate') {
  1959. return researched('tech-containerization');
  1960. } else {
  1961. return researched('tech-steel_containers');
  1962. }
  1963. }
  1964.  
  1965. get name() {
  1966. return this.id.charAt(0).toUpperCase() + this.id.slice(1)
  1967. }
  1968.  
  1969. get full() {
  1970. try {
  1971. let data = $('#cnt'+this.name+'s')[0].innerText.split(' / ');
  1972. return (parseInt(data[0]) == parseInt(data[1]));
  1973. } catch(e) {
  1974. console.log("Error:", this.id, "Full");
  1975. }
  1976. }
  1977.  
  1978. getResDep(resid) {
  1979. if (this.res === null) {
  1980. return null;
  1981. }
  1982. return this.res[resid.toLowerCase()];
  1983. }
  1984.  
  1985. click() {
  1986. // Ensuring no modal conflicts
  1987. console.log(this);
  1988.  
  1989. let addBtn = $('#createHead button');
  1990. if (this.id == 'crate'){
  1991. addBtn = addBtn[0];
  1992. }else{
  1993. addBtn = addBtn[1];
  1994. }
  1995. for (let i = 0; i < 10; i++) {
  1996. addBtn.click();
  1997. //console.log(this.id, i, addBtn, '#modal'+this.name+'s > span:nth-child(2) > button');
  1998. }
  1999.  
  2000. return true;
  2001. }
  2002. }
  2003. var storages = {};
  2004. function loadStorages() {
  2005. if (!settings.hasOwnProperty('actions')) {settings.actions = {};}
  2006. storages.Crate = new StorageAction('crate',
  2007. ['storage'], 0,
  2008. (resources.Lumber.unlocked) ?
  2009. {plywood:100}
  2010. :
  2011. {stone:2000});
  2012. storages.Container = new StorageAction('container',
  2013. ['storage'], 0,
  2014. {steel:1250});
  2015. }
  2016.  
  2017. class SupportProducer {
  2018. constructor(name, id, type, produce, consume, unlock_research) {
  2019. this.name = name;
  2020. this.id = id;
  2021. this.type = type;
  2022. this.produce = produce;
  2023. this.consume = consume;
  2024. this.unlock_research = unlock_research;
  2025. this.numLabel = null;
  2026. this.decBtn = null;
  2027. this.incBtn = null;
  2028. try {
  2029. this.numLabel = $('#'+this.id+' > a > .count')[0];
  2030. this.decBtn = $('#'+this.id+' > .off')[0];
  2031. this.incBtn = $('#'+this.id+' > .on')[0];
  2032. } catch(e) {
  2033. //console.log("Error: Could not load support producer", this.name);
  2034. }
  2035. }
  2036.  
  2037. get unlocked() {
  2038. if (this.unlock_research !== undefined) {
  2039. return $('#'+this.id).length > 0 && researched(this.unlock_research);
  2040. }
  2041. return $('#'+this.id).length > 0;
  2042. }
  2043.  
  2044. get numTotal() {
  2045. return parseInt(this.numLabel.innerText);
  2046. }
  2047.  
  2048. get numOn() {
  2049. return parseInt(this.incBtn.innerText);
  2050. }
  2051.  
  2052. get numOff() {
  2053. return parseInt(this.decBtn.innerText);
  2054. }
  2055. }
  2056. var elecProducers = {}
  2057. function loadElecProducers() {
  2058. elecProducers.Coal = new SupportProducer("Coal Powerplant", "city-coal_power", "electricity", 5, [{res:resources.Coal,cost:0.35}]);
  2059. elecProducers.Oil = new SupportProducer("Oil Powerplant", "city-oil_power", "electricity", 6, [{res:resources.Oil,cost:0.65}]);
  2060. elecProducers.Wind = new SupportProducer("Wind Turbine", "city-mill", "electricity", 1, [{res:resources.Food,cost:0.1}], "tech-windturbine");
  2061. elecProducers.Fission = new SupportProducer("Fission Reactor", "city-fission_power", "electricity",
  2062. researched('tech-breeder_reactor') ? 16 : 14,
  2063. [{res:resources.Uranium, cost:0.1}]);
  2064. }
  2065.  
  2066. class SupportConsumer {
  2067. constructor(name, id, type, consume, priority, unlock_research) {
  2068. this.name = name;
  2069. this.id = id;
  2070. this.type = type;
  2071. this.consume = consume;
  2072. this.unlock_research = unlock_research;
  2073. let skey = 'sup-prio' + this.id;
  2074. if(settings.hasOwnProperty(skey)){
  2075. this.priority = settings[skey];
  2076. } else {
  2077. this.priority = priority;
  2078. settings[skey] = priority;
  2079. }
  2080. this.numLabel = null;
  2081. this.decBtn = null;
  2082. this.incBtn = null;
  2083. try {
  2084. this.numLabel = $('#'+this.id+' > a > .count')[0];
  2085. this.decBtn = $('#'+this.id+' > .off')[0];
  2086. this.incBtn = $('#'+this.id+' > .on')[0];
  2087. } catch(e) {
  2088. //console.log("Error: Could not load support consumer", this.name);
  2089. }
  2090. }
  2091.  
  2092. get unlocked() {
  2093. if (this.unlock_research !== undefined) {
  2094. return $('#'+this.id).length > 0 && researched(this.unlock_research);
  2095. }
  2096. return $('#'+this.id).length > 0;
  2097. }
  2098.  
  2099. get numTotal() {
  2100. return parseInt(this.numLabel.innerText);
  2101. }
  2102.  
  2103. get numOn() {
  2104. return parseInt(this.incBtn.innerText);
  2105. }
  2106.  
  2107. get numOff() {
  2108. return parseInt(this.decBtn.innerText);
  2109. }
  2110.  
  2111. lowerPriority() {
  2112. if (this.priority != 0) {
  2113. this.priority -= 1;
  2114. console.log("Lowering", this.name, "Priority", this.priority);
  2115. settings['sup-prio' + this.id] = this.priority;
  2116. }
  2117. }
  2118.  
  2119. higherPriority() {
  2120. if (this.priority != 99) {
  2121. this.priority += 1;
  2122. console.log("Increasing", this.name, "Priority", this.priority);
  2123. settings['sup-prio' + this.id] = this.priority;
  2124. }
  2125. }
  2126. }
  2127. var elecConsumers = {}
  2128. function loadElecConsumers() {
  2129. elecConsumers["Rock Quarry"] = new SupportConsumer("Rock Quarry", "city-rock_quarry", "electricity", 1, 1, "tech-mine_conveyor");
  2130. elecConsumers.Sawmill = new SupportConsumer("Sawmill", "city-sawmill", "electricity", 1, 1);
  2131. elecConsumers.Mine = new SupportConsumer("Mine", "city-mine", "electricity", 1, 2, "tech-mine_conveyor");
  2132. elecConsumers["Coal Mine"] = new SupportConsumer("Coal Mine", "city-coal_mine", "electricity", 1, 2, "tech-mine_conveyor");
  2133. elecConsumers["Cement Plant"] = new SupportConsumer("Cement Plant", "city-cement_plant", "electricity", 2, 3, "tech-screw_conveyor");
  2134. elecConsumers.Apartment = new SupportConsumer("Apartment", "city-apartment", "electricity", 1, 9);
  2135. elecConsumers.Factory = new SupportConsumer("Factory", "city-factory", "electricity", 3, 9);
  2136. elecConsumers.Wardenclyffe = new SupportConsumer("Wardenclyffe", "city-wardenclyffe", "electricity", 2, 9);
  2137. elecConsumers["Bioscience Lab"] = new SupportConsumer("Bioscience Lab", "city-biolab", "electricity", 2, 9);
  2138. elecConsumers["Moon Base"] = new SupportConsumer("Moon Base", "space-moon_base", "electricity", 4, 9);
  2139. }
  2140.  
  2141. class Job {
  2142. constructor(id, priority) {
  2143. this.id = id;
  2144. if (!settings.jobs.hasOwnProperty(this.id)) {settings.jobs[this.id] = {};}
  2145. if (!settings.jobs[this.id].hasOwnProperty('priority')) {settings.jobs[this.id].priority = priority;}
  2146. }
  2147.  
  2148. get _priority() {return settings.jobs[this.id].priority;}
  2149. set _priority(priority) {settings.jobs[this.id].priority = priority;}
  2150.  
  2151. get name() {
  2152. try {
  2153. let _name = document.querySelector('#civ-'+this.id+' > .job_label > h3').innerText;
  2154. if (_name === null || _name === undefined) {
  2155. return this.id;
  2156. }
  2157. return _name;
  2158. } catch(e) {
  2159. console.log("Error:", this.id, "Name");
  2160. return null;
  2161. }
  2162. }
  2163.  
  2164. get employed() {
  2165. try {
  2166. let employees = document.querySelector('#civ-'+this.id+' > .job_label > .count');
  2167. return parseInt(employees.innerText.split('/')[0]);
  2168. } catch(e) {
  2169. console.log("Error:", this.id, "Employed");
  2170. return null;
  2171. }
  2172. }
  2173.  
  2174. get maxEmployed() {
  2175. try {
  2176. let employees = document.querySelector('#civ-'+this.id+' > .job_label > .count');
  2177. return parseInt((employees.innerText.split('/').length > 1) ? employees.innerText.split('/')[1] : -1);
  2178. } catch(e) {
  2179. console.log("Error:", this.id, "MaxEmployed");
  2180. return null;
  2181. }
  2182. }
  2183.  
  2184. get priority() {
  2185. return this._priority;
  2186. }
  2187.  
  2188. lowerPriority() {
  2189. if (this._priority == 0) {return;}
  2190. this._priority -= 1;
  2191. updateSettings();
  2192. console.log("Lowering", this.id, "Priority", this._priority);
  2193. }
  2194.  
  2195. higherPriority() {
  2196. if (this._priority == 9) {return;}
  2197. this._priority += 1;
  2198. updateSettings();
  2199. console.log("Increasing", this.name, "Priority", this._priority);
  2200. }
  2201.  
  2202. get unlocked() {
  2203. // Finding civicsTab
  2204. try {
  2205. let nav = $('#mainColumn > .content > .b-tabs > .tabs > ul > li > a > span');
  2206. let civicsOn = false;
  2207. for (let i = 0;i < nav.length;i++) {
  2208. if (nav[i].innerText == "Civics") {
  2209. let nth = i+1;
  2210. civicsOn = $('#mainColumn > .content > .b-tabs > .tabs > ul > li:nth-child('+nth+')')[0].style.display != 'none';
  2211. break;
  2212. }
  2213. }
  2214. return $('#civ-'+this.id)[0].style.display != 'none' && civicsOn;
  2215. } catch(e) {
  2216. console.log("Error:", this.id, "Unlocked");
  2217. return false;
  2218. }
  2219. }
  2220.  
  2221. hire() {
  2222. try {
  2223. let hireBtn = document.querySelector('#civ-'+this.id+' > .controls > .add');
  2224. hireBtn.click();
  2225. return true;
  2226. } catch(e) {
  2227. console.log("Error:", this.id, "Hire");
  2228. return false;
  2229. }
  2230. }
  2231.  
  2232. fire() {
  2233. try {
  2234. let fireBtn = document.querySelector('#civ-'+this.id+' > .controls > .sub');
  2235. fireBtn.click();
  2236. return true;
  2237. } catch(e) {
  2238. console.log("Error:", this.id, "Fire");
  2239. return false;
  2240. }
  2241. }
  2242. }
  2243. class Unemployed extends Job {
  2244. constructor(id, priority) {
  2245. super(id, priority);
  2246. }
  2247.  
  2248. get priority() {
  2249. if (this.name == 'Hunter') {
  2250. return this._priority;
  2251. } else {
  2252. return 0;
  2253. }
  2254. }
  2255. }
  2256. class Craftsman extends Job {
  2257. constructor(id, priority) {
  2258. super(id, priority);
  2259. }
  2260.  
  2261. get name() {
  2262. return "Craftsman";
  2263. }
  2264.  
  2265. get employed() {
  2266. try {
  2267. let employees = document.querySelector('#foundry > .job > .foundry > .count');
  2268. return parseInt(employees.innerText.split('/')[0]);
  2269. } catch(e) {
  2270. console.log("Error:", this.id, "Employed");
  2271. return null;
  2272. }
  2273. }
  2274.  
  2275. get maxEmployed() {
  2276. try {
  2277. let employees = document.querySelector('#foundry > .job > .foundry > .count');
  2278. return parseInt((employees.innerText.split('/').length > 1) ? employees.innerText.split('/')[1] : -1);
  2279. } catch(e) {
  2280. console.log("Error:", this.id, "MaxEmployed");
  2281. return null;
  2282. }
  2283. }
  2284.  
  2285. get unlocked() {
  2286. try {
  2287. // Finding civicsTab
  2288. let nav = $('#mainColumn > .content > .b-tabs > .tabs > ul > li > a > span');
  2289. let civicsOn = false;
  2290. for (let i = 0;i < nav.length;i++) {
  2291. if (nav[i].innerText == "Civics") {
  2292. let nth = i+1;
  2293. civicsOn = $('#mainColumn > .content > .b-tabs > .tabs > ul > li:nth-child('+nth+')')[0].style.display != 'none';
  2294. break;
  2295. }
  2296. }
  2297. return $('#foundry')[0].style.display != 'none' && civicsOn && $('#foundry')[0].children.length > 0;
  2298. } catch(e) {
  2299. console.log("Error:", this.id, "Unlocked");
  2300. return false;
  2301. }
  2302. }
  2303.  
  2304. hire() {
  2305. try {
  2306. let hireBtn = document.querySelectorAll('#foundry .job')[1].children[1].children[1];
  2307. hireBtn.click();
  2308. return true;
  2309. } catch(e) {
  2310. console.log("Error:", this.id, "Hire");
  2311. return false;
  2312. }
  2313. }
  2314.  
  2315. fire() {
  2316. try {
  2317. let fireBtn = document.querySelectorAll('#foundry .job')[1].children[1].children[0];
  2318. fireBtn.click();
  2319. } catch(e) {
  2320. console.log("Error:", this.id, "Fire");
  2321. return false;
  2322. }
  2323. }
  2324. }
  2325. var jobs = {};
  2326. function loadJobs() {
  2327. if (!settings.hasOwnProperty('jobs')) {settings.jobs = {};}
  2328. jobs.free = new Unemployed("free", 0);
  2329. jobs.farmer = new Job("farmer", 1);
  2330. jobs.lumberjack = new Job("lumberjack", 3);
  2331. jobs.quarry_worker = new Job("quarry_worker", 3);
  2332. jobs.miner = new Job("miner", 4);
  2333. jobs.coal_miner = new Job("coal_miner", 4);
  2334. jobs.cement_worker = new Job("cement_worker", 4);
  2335. jobs.entertainer = new Job("entertainer", 8);
  2336. jobs.professor = new Job("professor", 9);
  2337. jobs.scientist = new Job("scientist", 9);
  2338. jobs.banker = new Job("banker", 9);
  2339. jobs.colonist = new Job("colonist", 7);
  2340. jobs.space_miner = new Job("space_miner", 7);
  2341. jobs.craftsman = new Craftsman("craftsman", 9);
  2342. jobs.hell_surveyor = new Craftsman("hell_surveyor", 9);
  2343. }
  2344.  
  2345. class CraftJob extends Job {
  2346. constructor(id, priority) {
  2347. super(id, priority);
  2348. }
  2349. get hireBtn(){
  2350. if (!this.hireBtnCache){
  2351. let btn = document.getElementById('craft'+this.id);
  2352. if (btn){
  2353. this.hideBtnCache = btn.parentNode.children[1].children[1];
  2354. return this.hideBtnCache;
  2355. }
  2356. return null;
  2357. }
  2358. return this.hideBtnCache;
  2359. }
  2360. get fireBtn() {
  2361. if (!this.fireBtnCache){
  2362. let btn = document.getElementById('craft'+this.id);
  2363. if (btn){
  2364. this.fireBtnCache = btn.parentNode.children[1].children[0];
  2365. return this.fireBtnCache;
  2366. }
  2367. return null;
  2368. }
  2369. return this.fireBtnCache;
  2370. }
  2371.  
  2372. get name() {
  2373. try {
  2374. let _name = document.querySelector('#craft'+this.id+' > h3').innerText;
  2375. if (_name === null || _name === undefined) {
  2376. return this.id;
  2377. }
  2378. return _name;
  2379. } catch(e) {
  2380. console.log("Error:", this.id, "Name");
  2381. return null;
  2382. }
  2383. }
  2384.  
  2385. get employed() {
  2386. try {
  2387. let employees = document.querySelector('#craft'+this.id+' > .count');
  2388. return parseInt(employees.innerText.split('/')[0]);
  2389. } catch(e) {
  2390. console.log("Error:", this.id, "Employed");
  2391. return null;
  2392. }
  2393. }
  2394. get maxEmployed() {
  2395. try {
  2396. let employees = document.querySelector('#craft'+this.id+' > .count');
  2397. return parseInt((employees.innerText.split('/').length > 1) ? employees.innerText.split('/')[1] : -1);
  2398. } catch(e) {
  2399. console.log("Error:", this.id, "MaxEmployed");
  2400. return null;
  2401. }
  2402. }
  2403.  
  2404. get unlocked() {
  2405. // Finding civicsTab
  2406. let nav = $('#mainColumn > .content > .b-tabs > .tabs > ul > li > a > span');
  2407. let civicsOn = false;
  2408. for (let i = 0;i < nav.length;i++) {
  2409. if (nav[i].innerText == "Civics") {
  2410. let nth = i+1;
  2411. civicsOn = $('#mainColumn > .content > .b-tabs > .tabs > ul > li:nth-child('+nth+')')[0].style.display != 'none';
  2412. break;
  2413. }
  2414. }
  2415. return (typeof $('#craft'+this.id)[0] !== 'undefined') && civicsOn;
  2416. }
  2417.  
  2418. hire() {
  2419. try {
  2420. this.hireBtn.click();
  2421. return true;
  2422. } catch(e) {
  2423. console.log("Error:", this.id, "Hire");
  2424. return false;
  2425. }
  2426. }
  2427. fire() {
  2428. try {
  2429. this.fireBtn.click();
  2430. return true;
  2431. } catch(e) {
  2432. console.log("Error:", this.id, "Fire");
  2433. return false;
  2434. }
  2435. }
  2436. }
  2437. var craftJobs = {};
  2438. function loadCraftJobs() {
  2439. if (!settings.hasOwnProperty('jobs')) {settings.jobs = {};}
  2440. craftJobs.Plywood = new CraftJob("Plywood", 5);
  2441. craftJobs.Brick = new CraftJob("Brick", 5);
  2442. craftJobs.Wrought_Iron = new CraftJob("Wrought_Iron", 5);
  2443. craftJobs.Sheet_Metal = new CraftJob("Sheet_Metal", 5);
  2444. craftJobs.Mythril = new CraftJob("Mythril", 5);
  2445. craftJobs.Aerogel = new CraftJob("Aerogel", 5);
  2446.  
  2447. }
  2448.  
  2449. let foodBtn = null;
  2450. let lumberBtn = null;
  2451. let stoneBtn = null;
  2452. let rnaBtn = null;
  2453. let dnaBtn = null;
  2454. function loadFarm () {
  2455. try {
  2456. foodBtn = document.getElementById("city-food").getElementsByTagName("a")[0];
  2457. } catch(e) {
  2458. //console.log("Error: Food button could not be loaded");
  2459. }
  2460. try {
  2461. lumberBtn = document.getElementById("city-lumber").getElementsByTagName("a")[0];
  2462. } catch(e) {
  2463. //console.log("Error: Lumber button could not be loaded");
  2464. }
  2465. try {
  2466. stoneBtn = document.getElementById("city-stone").getElementsByTagName("a")[0];
  2467. } catch(e) {
  2468. //console.log("Error :Stone button could not be loaded");
  2469. }
  2470. try {
  2471. rnaBtn = document.getElementById("evo-rna").getElementsByTagName("a")[0];
  2472. } catch(e) {
  2473. //console.log("Error: RNA button could not be loaded");
  2474. }
  2475. try {
  2476. dnaBtn = document.getElementById("evo-dna").getElementsByTagName("a")[0];
  2477. } catch(e) {
  2478. //console.log("Error :DNA button could not be loaded");
  2479. }
  2480. }
  2481.  
  2482. /***
  2483. *
  2484. * Settings
  2485. *
  2486. ***/
  2487.  
  2488. function loadSettings() {
  2489. // Farm
  2490. loadFarm();
  2491. // Resources
  2492. loadResources();
  2493. // Storages
  2494. loadStorages();
  2495. // Crafting
  2496. loadCraftableResources();
  2497. // Buildings
  2498. loadBuildings();
  2499. // Support
  2500. loadElecProducers();
  2501. loadElecConsumers();
  2502. // Jobs
  2503. loadJobs();
  2504. loadCraftJobs();
  2505. // Research
  2506. loadResearches();
  2507. // ARPA
  2508. loadArpas();
  2509. if (!settings.hasOwnProperty('autoPrint')) {
  2510. settings.autoPrint = true;
  2511. }
  2512. if (!settings.hasOwnProperty('autoFarm')) {
  2513. settings.autoFarm = false;
  2514. }
  2515. if (!settings.hasOwnProperty('autoEvolution')) {
  2516. settings.autoEvolution = false;
  2517. }
  2518. if (!settings.hasOwnProperty('evolution')) {
  2519. settings.evolution = "antid";
  2520. }
  2521. if (!settings.hasOwnProperty('Plasmid')) {
  2522. settings.Plasmid = false;
  2523. }
  2524. if (!settings.hasOwnProperty('Craft')) {
  2525. settings.Craft = false;
  2526. }
  2527. if (!settings.hasOwnProperty('CRISPR')) {
  2528. settings.CRISPR = false;
  2529. }
  2530. if (!settings.hasOwnProperty('Trade')) {
  2531. settings.Trade = false;
  2532. }
  2533. if (!settings.hasOwnProperty('autoCraft')) {
  2534. settings.autoCraft = false;
  2535. }
  2536. if (!settings.hasOwnProperty('autoBuild')) {
  2537. settings.autoBuild = false;
  2538. }
  2539. if (!settings.hasOwnProperty('autoSmelter')) {
  2540. settings.autoSmelter = false;
  2541. }
  2542. if (!settings.hasOwnProperty('autoFactory')) {
  2543. settings.autoFactory = false;
  2544. }
  2545. if (!settings.hasOwnProperty('autoSupport')) {
  2546. settings.autoSupport = false;
  2547. }
  2548. if (!settings.hasOwnProperty('autoEmploy')) {
  2549. settings.autoEmploy = false;
  2550. }
  2551. if (!settings.hasOwnProperty('autoTax')) {
  2552. settings.autoTax = false;
  2553. }
  2554. if (!settings.hasOwnProperty('defaultMorale')) {
  2555. settings.defaultMorale = 100;
  2556. }
  2557. if (!settings.hasOwnProperty('autoBattle')) {
  2558. settings.autoBattle = false;
  2559. }
  2560. if (!settings.hasOwnProperty('autoResearch')) {
  2561. settings.autoResearch = false;
  2562. }
  2563. if (!settings.hasOwnProperty('fanORanth')) {
  2564. settings.fanORanth = "fanaticism";
  2565. }
  2566. if (!settings.hasOwnProperty('studyORdeify')) {
  2567. settings.studyORdeify = "study";
  2568. }
  2569. if (!settings.hasOwnProperty('autoMarket')) {
  2570. settings.autoMarket = false;
  2571. }
  2572. if (!settings.hasOwnProperty('minimumMoney')) {
  2573. settings.minimumMoney = 0;
  2574. }
  2575. if (!settings.hasOwnProperty('autoARPA')) {
  2576. settings.autoARPA = false;
  2577. }
  2578. if (!settings.hasOwnProperty('autoReset')) {
  2579. settings.autoReset = false;
  2580. }
  2581. if (!settings.hasOwnProperty('arpa')) {
  2582. settings.arpa = {
  2583. lhc: false,
  2584. stock_exchange: false,
  2585. monument: false
  2586. };
  2587. }
  2588. if (!settings.hasOwnProperty('log')) {settings.log = []};
  2589. //console.log("Finished loading settings");
  2590. }
  2591. loadSettings();
  2592.  
  2593. function updateSettings(){
  2594. localStorage.setItem('settings', JSON.stringify(settings));
  2595. }
  2596.  
  2597. function importSettings() {
  2598. console.log("Importing Settings");
  2599. if ($('textarea#settingsImportExport').val().length > 0){
  2600. let settingStr = $('textarea#settingsImportExport').val()
  2601. settings = JSON.parse(settingStr);
  2602. updateSettings();
  2603. resetUI();
  2604. }
  2605. }
  2606.  
  2607. function exportSettings() {
  2608. console.log("Exporting Settings");
  2609. $('textarea#settingsImportExport').val(JSON.stringify(settings));
  2610. $('textarea#settingsImportExport').select();
  2611. }
  2612.  
  2613. /***
  2614. *
  2615. * automation functions
  2616. *
  2617. ***/
  2618.  
  2619. function farm() {
  2620. if(foodBtn!==null){foodBtn.click();}
  2621. if(lumberBtn!==null){lumberBtn.click();}
  2622. if(stoneBtn!==null){stoneBtn.click();}
  2623. if(rnaBtn!==null){rnaBtn.click();}
  2624. if(dnaBtn!==null){dnaBtn.click();}
  2625. }
  2626.  
  2627. let farmInterval = null;
  2628. function autoFarm() {
  2629. if(settings.autoFarm && farmInterval === null) {
  2630. farmInterval = setInterval(farm, 10);
  2631. } else {
  2632. if (!settings.autoFarm && !(farmInterval === null)) {
  2633. clearInterval(farmInterval);
  2634. farmInterval = null;
  2635. }
  2636. }
  2637. }
  2638.  
  2639. let evoFarmActions = ["evo-rna", "evo-dna"];
  2640. let evoRaceActions = ["evo-phagocytosis", "evo-chitin", "evo-chloroplasts",
  2641. "evo-eggshell", "evo-mammals", "evo-athropods",
  2642. "evo-ectothermic", "evo-endothermic",
  2643. "evo-humanoid", "evo-gigantism", "evo-animalism", "evo-dwarfism",
  2644. "evo-aquatic", "evo-demonic",
  2645. "evo-entish", "evo-cacti",
  2646. "evo-sporgar", "evo-shroomi",
  2647. "evo-arraak", "evo-pterodacti", "evo-dracnid",
  2648. "evo-tortoisan", "evo-gecko", "evo-slitheryn",
  2649. "evo-human", "evo-elven", "evo-orc",
  2650. "evo-orge", "evo-cyclops", "evo-troll",
  2651. "evo-kobold", "evo-goblin", "evo-gnome",
  2652. "evo-cath", "evo-wolven", "evo-centuar",
  2653. "evo-mantis", "evo-scorpid", "evo-antid",
  2654. "evo-sharkin", "evo-octigoran", "evo-balorg", "evo-imp"];
  2655. let evoRaceTrees = {
  2656. "entish":["evo-chloroplasts", "evo-entish"],
  2657. "cacti":["evo-chloroplasts", "evo-cacti"],
  2658. "sporgar":["evo-chitin", "evo-sporgar"],
  2659. "shroomi":["evo-chitin", "evo-shroomi"],
  2660. "arraak":["evo-phagocytosis", "evo-eggshell", "evo-endothermic", "evo-arraak"],
  2661. "pterodacti":["evo-phagocytosis", "evo-eggshell", "evo-endothermic", "evo-pterodacti"],
  2662. "dracnid":["evo-phagocytosis", "evo-eggshell", "evo-endothermic", "evo-dracnid"],
  2663. "tortoisan":["evo-phagocytosis", "evo-eggshell", "evo-ectothermic", "evo-tortoisan"],
  2664. "gecko":["evo-phagocytosis", "evo-eggshell", "evo-ectothermic", "evo-gecko"],
  2665. "slitheryn":["evo-phagocytosis", "evo-eggshell", "evo-ectothermic", "evo-slitheryn"],
  2666. "human":["evo-phagocytosis", "evo-mammals", "evo-humanoid", "evo-human"],
  2667. "elven":["evo-phagocytosis", "evo-mammals", "evo-humanoid", "evo-elven"],
  2668. "orc":["evo-phagocytosis", "evo-mammals", "evo-humanoid", "evo-orc"],
  2669. "orge":["evo-phagocytosis", "evo-mammals", "evo-gigantism", "evo-orge"],
  2670. "cyclops":["evo-phagocytosis", "evo-mammals", "evo-gigantism", "evo-cyclops"],
  2671. "troll":["evo-phagocytosis", "evo-mammals", "evo-gigantism", "evo-troll"],
  2672. "kobold":["evo-phagocytosis", "evo-mammals", "evo-dwarfism", "evo-kobold"],
  2673. "goblin":["evo-phagocytosis", "evo-mammals", "evo-dwarfism", "evo-goblin"],
  2674. "gnome":["evo-phagocytosis", "evo-mammals", "evo-dwarfism", "evo-gnome"],
  2675. "cath":["evo-phagocytosis", "evo-mammals", "evo-animalism", "evo-cath"],
  2676. "wolven":["evo-phagocytosis", "evo-mammals", "evo-animalism", "evo-wolven"],
  2677. "centuar":["evo-phagocytosis", "evo-mammals", "evo-animalism", "evo-centuar"],
  2678. "mantis":["evo-phagocytosis", "evo-athropods", "evo-mantis"],
  2679. "scorpid":["evo-phagocytosis", "evo-athropods", "evo-scorpid"],
  2680. "antid":["evo-phagocytosis", "evo-athropods", "evo-antid"],
  2681. "sharkin":["evo-phagocytosis", "evo-aquatic", "evo-sharkin"],
  2682. "octigoran":["evo-phagocytosis", "evo-aquatic", "evo-octigoran"],
  2683. "octigoran":["evo-phagocytosis", "evo-aquatic", "evo-octigoran"],
  2684. "balorg":["evo-phagocytosis", "evo-mammals", "evo-demonic", "evo-balorg"],
  2685. "imp":["evo-phagocytosis", "evo-mammals", "evo-demonic", "evo-imp"]
  2686. };
  2687. let maxEvo = {
  2688. "evo-membrane":5,
  2689. "evo-organelles":1,
  2690. "evo-nucleus":1,
  2691. "evo-eukaryotic_cell":2,
  2692. "evo-mitochondria":4
  2693. };
  2694. function autoEvolution() {
  2695. let actions = document.querySelectorAll('#evolution .action');
  2696. let seenChallenges = false;
  2697. for(let i = 0; i < actions.length; i++){
  2698. // Checking if purchasable
  2699. let action = actions[i];
  2700. if(action.className.indexOf("cna") < 0){
  2701. // Checking if farming button
  2702. if(action.id == "evo-rna" || action.id == "evo-dna") {continue;}
  2703. // Stop buying garbage you idiot
  2704. if(action.id in maxEvo && parseInt($('#'+action.id+' > a > .count')[0].innerText) > maxEvo[action.id]) {continue;}
  2705. // Don't take sentience
  2706. if(action.id == "evo-sentience") {continue;}
  2707. // Check for challenge runs
  2708. if(action.id == "evo-plasmid" && !settings.Plasmid) {continue;}
  2709. if(action.id == "evo-craft" && !settings.Craft) {continue;}
  2710. if(action.id == "evo-crispr" && !settings.CRISPR) {continue;}
  2711. if(action.id == "evo-trade" && !settings.Trade) {continue;}
  2712. if(action.id == "evo-junker" && !settings.Junker) {continue;}
  2713. if(action.id == "evo-decay" && !settings.Decay) {continue;}
  2714. if(action.id == "evo-joyless" && !settings.Joyless) {
  2715. seenChallenges = true;
  2716. continue;
  2717. }
  2718.  
  2719. // Checking for race decision tree
  2720. if(evoRaceActions.includes(action.id) && !evoRaceTrees[settings.evolution].includes(action.id)) {continue;}
  2721. action.children[0].click();
  2722. if(settings.autoPrint){messageQueue("[AUTO-EVOLVE] " + action.children[0].children[0].innerText,'dark');}
  2723. return;
  2724. }
  2725. }
  2726. if(seenChallenges){
  2727. // made our choices, go to next level
  2728. $('#evo-sentience')[0].children[0].click();
  2729. }
  2730. }
  2731.  
  2732. function autoCraft() {
  2733. //console.log("AutoCrafting", craftableResources);
  2734. for (let x in craftableResources) {
  2735. craftableResources[x].craft();
  2736. }
  2737. }
  2738.  
  2739. let storage = {};
  2740. function getMaxCrates() {
  2741. let crateMax = 0;
  2742. // Freight Yards
  2743. if (buildings['city-storage_yard'].unlocked) {
  2744. let size = researched('tech-cranes') ? 20 : 10;
  2745. if (researched('tech-wc_conquest')||researched('tech-wc_morale')||researched('tech-wc_money')||researched('tech-wc_reject')) {
  2746. size += 10;
  2747. }
  2748. if (researched('tech-matter_compression')){
  2749. size *= 2;
  2750. }
  2751. crateMax += (buildings['city-storage_yard'].numTotal * size);
  2752. }
  2753. // Wharfs
  2754. if (buildings['city-wharf'].unlocked) {
  2755. let vol = (researched('tech-wc_conquest')||researched('tech-wc_morale')||researched('tech-wc_money')||researched('tech-wc_reject')) ? 15 : 10
  2756. if (researched('tech-matter_compression')){
  2757. vol *= 2;
  2758. }
  2759. crateMax += (buildings['city-wharf'].numTotal * vol);
  2760. }
  2761. return crateMax;
  2762. }
  2763. function getMaxContainers() {
  2764. let containerMax = 0;
  2765. // Container Ports
  2766. if (buildings['city-warehouse'].unlocked) {
  2767. let size = researched('tech-gantry_crane') ? 20 : 10;
  2768. if (researched('tech-wc_conquest')||researched('tech-wc_morale')||researched('tech-wc_money')||researched('tech-wc_reject')) {
  2769. size += 10;
  2770. }
  2771. if (researched('tech-matter_compression')){
  2772. size *= 2;
  2773. }
  2774. containerMax += (buildings['city-warehouse'].numTotal * size);
  2775. }
  2776. // Wharfs
  2777. if (buildings['city-wharf'].unlocked) {
  2778. let vol = (researched('tech-wc_conquest')||researched('tech-wc_morale')||researched('tech-wc_money')||researched('tech-wc_reject')) ? 15 : 10
  2779. if (researched('tech-matter_compression')){
  2780. vol *= 2;
  2781. }
  2782. containerMax += (buildings['city-wharf'].numTotal * vol);
  2783. }
  2784. // Garages
  2785. if (buildings['space-garage'].unlocked) {
  2786. let g_vol = researched('tech-dimensional_compression') ? 20 + arpas['lhc'].rank : 20;
  2787. if (researched('tech-wc_conquest')||researched('tech-wc_morale')||researched('tech-wc_money')||researched('tech-wc_reject')) {
  2788. g_vol += 10;
  2789. }
  2790. containerMax += (buildings['space-garage'].numTotal * g_vol);
  2791. }
  2792. return containerMax;
  2793. }
  2794. function getCurrentStorageNum(id) {
  2795. //console.log("Getting Current Storage", id);
  2796. storage[id] = {};
  2797. let str = null;
  2798. try {
  2799. str = $('#stack-' + id + ' .current')[0].innerText;
  2800. storage[id].current_crates = parseInt(str);
  2801. } catch(e) {
  2802. console.log("Error in reading crates", id);
  2803. }
  2804. try {
  2805. str = $('#stack-' + id + ' .current')[1].innerText;
  2806. storage[id].current_containers = parseInt(str);
  2807. } catch(e) {
  2808. console.log("Error in reading containers", id);
  2809. }
  2810. console.log(id, storage[id]);
  2811. }
  2812. function getCurrentStorageTotal() {
  2813. storage = {};
  2814. for (var x in resources) {
  2815. if (!resources[x].crateable || !resources[x].unlocked) {
  2816. continue;
  2817. }
  2818. getCurrentStorageNum(x);
  2819. }
  2820. }
  2821. function removeStorage(excessStorage) {
  2822. for (let i = 0;i < excessStorage.length;i++) {
  2823. let id = excessStorage[i];
  2824. console.log("Removing storage", id);
  2825. // Removing unneeded crates
  2826. console.log(id, storage[id].needed_crates, storage[id].needed_containers);
  2827. if (storage[id].needed_crates < 0) {
  2828. let removeBtn = $('#stack-' + id + ' .sub');
  2829. for (let j = 0;j < -storage[id].needed_crates;j++) {
  2830. removeBtn[0].click();
  2831. }
  2832. console.log("Removed", -storage[id].needed_crates, "Crates");
  2833. }
  2834. // Removing unneeded containers
  2835. if (researched('tech-steel_containers') && storage[id].needed_containers < 0) {
  2836. let removeBtn = $('#stack-' + id + ' .sub');
  2837. for (let j = 0; j < -storage[id].needed_containers; j++) {
  2838. removeBtn[1].click();
  2839. }
  2840. console.log("Removed", -storage[id].needed_containers, "Containers");
  2841. }
  2842. }
  2843. return excessStorage.length * 300;
  2844. }
  2845. function addStorage(neededStorage) {
  2846. for (let i = 0;i < neededStorage.length;i++) {
  2847. let id = neededStorage[i];
  2848. console.log("Adding Storage", id);
  2849. // Checking if modal already open
  2850. let addBtn = $('#stack-' + id + ' .add');
  2851.  
  2852.  
  2853. // Adding needed crates
  2854. if (storage[id].needed_crates > 0) {
  2855. console.log("Adding", storage[id].needed_crates, "Crates");
  2856. for (let j = 0; j < storage[id].needed_crates; j++) {
  2857. addBtn[0].click();
  2858. }
  2859. }
  2860. // Adding needed containers
  2861. if (researched('tech-steel_containers') && storage[id].needed_containers > 0) {
  2862. console.log("Adding", storage[id].needed_containers, "Containers");
  2863. for (let j = 0; j < storage[id].needed_containers; j++) {
  2864. addBtn[1].click();
  2865. }
  2866. }
  2867. }
  2868. }
  2869. function autoStorage() {
  2870. // Don't do autoStorage if haven't unlocked storage
  2871. if (!researched('tech-containerization')) {return;}
  2872.  
  2873. let crateBtn = $('#createHead .crate button');
  2874. let containerBtn = $('#createHead .container button');
  2875. [...Array(10)].forEach(() => crateBtn.click());
  2876. if (researched('tech-steel_containers')){
  2877. [...Array(10)].forEach(() => containerBtn.click());
  2878. }
  2879.  
  2880. // Finding
  2881. let crateMax = getMaxCrates();
  2882. let freeCrates = parseInt($('#cntCrates')[0].innerText.split(' / ')[0]);
  2883. let containerMax = getMaxContainers();
  2884. let freeContainers = parseInt($('#cntContainers')[0].innerText.split(' / ')[0]);
  2885.  
  2886. getCurrentStorageTotal();
  2887.  
  2888. // Finding total used crates;
  2889. let curCrateTotal = 0;
  2890. let curContainerTotal = 0;
  2891. let error = false;
  2892. for (var x in storage) {
  2893. //console.log(x, storage[x]);
  2894. // If there was an error in reading the storage values
  2895. if (!storage[x].hasOwnProperty('current_crates')) {error = true;break;}
  2896. curCrateTotal += storage[x].current_crates;
  2897. curContainerTotal += storage[x].current_containers;
  2898. }
  2899. // Checking if error occured
  2900. if (error) {
  2901. console.log("Error in counting storage");
  2902. return;
  2903. }
  2904.  
  2905. console.log("Current Crate Usage", curCrateTotal);
  2906. console.log("Free Crates", freeCrates);
  2907. console.log("Max Crates", crateMax);
  2908. console.log("Current Container Usage", curContainerTotal);
  2909. console.log("Free Containers", freeContainers);
  2910. console.log("Max Containers", containerMax);
  2911.  
  2912. // Getting total number of usable storage
  2913. let totalCrates = curCrateTotal + freeCrates;
  2914. let totalContainers = curContainerTotal + freeContainers;
  2915. // Getting total priority
  2916. let totalPriority = 0;
  2917. for (x in storage) {
  2918. totalPriority += resources[x].storePriority;
  2919. }
  2920. // Calculating crate differentials
  2921. for (x in storage) {
  2922. storage[x].wanted_crates = Math.round(totalCrates * resources[x].storePriority / totalPriority);
  2923. storage[x].wanted_crates = Math.max(storage[x].wanted_crates, resources[x].storeMin);
  2924. storage[x].needed_crates = storage[x].wanted_crates - storage[x].current_crates;
  2925. storage[x].wanted_containers = Math.round(totalContainers * resources[x].storePriority / totalPriority);
  2926. storage[x].needed_containers = storage[x].wanted_containers - storage[x].current_containers;
  2927. console.log(
  2928. x,
  2929. "CR_WANT", storage[x].wanted_crates,
  2930. "CR_NEED", storage[x].needed_crates,
  2931. "CO_WANT", storage[x].wanted_containers,
  2932. "CO_NEED", storage[x].needed_containers);
  2933. }
  2934. // Removing extra storage
  2935. let excessStorage = [];
  2936. for (x in storage) {
  2937. if (storage[x].needed_crates < 0) {
  2938. excessStorage.push(x);
  2939. } else if (researched('tech-steel_containers') && storage[x].needed_containers < 0) {
  2940. excessStorage.push(x);
  2941. }
  2942. }
  2943. // Must wait for removing crates
  2944. console.log("Excess", excessStorage);
  2945. removeStorage(excessStorage);
  2946.  
  2947. // Adding needed storage
  2948. let neededStorage = [];
  2949. for (x in storage) {
  2950. if (storage[x].needed_crates > 0) {
  2951. neededStorage.push(x);
  2952. } else if (researched('tech-steel_containers') && storage[x].needed_containers > 0) {
  2953. neededStorage.push(x);
  2954. }
  2955. }
  2956. neededStorage.sort(function(a, b) {
  2957. if (resources[b].storeMin > resources[a].storeMin) {
  2958. return 1;
  2959. }
  2960. return resources[b].store_priority - resources[a].store_priority;
  2961. });
  2962. //console.log(neededStorage);
  2963. addStorage(neededStorage);
  2964. console.log('Finished Adding Storage');
  2965. }
  2966.  
  2967. class AutoBattler {
  2968. constructor() {
  2969. this.battleButton = document.querySelector('#garrison > div:nth-child(4) > div:nth-child(2) > span > button');
  2970. this.addBattalion = document.querySelector('#battalion > .add');
  2971. this.hireButton = document.querySelector('#garrison .bunk button');
  2972. this.armySize = document.querySelector('#battalion .current');
  2973. this.lowerCampaign = document.querySelector('#tactics > .sub');
  2974. this.higherCampaign = document.querySelector('#tactics > .add');
  2975. this.campaignStrengths = [
  2976. { name: "Ambush", rating: 10 },
  2977. { name: "Raid", rating: 50 },
  2978. { name: "Pillage", rating: 100 },
  2979. { name: "Assault", rating: 200 },
  2980. { name: "Siege", rating: 500 }
  2981. ];
  2982. this.addToFortress = document.querySelectorAll('#fort .add')[0];
  2983. this.addToPatrols = document.querySelectorAll('#fort .add')[1];
  2984. this.attractor = document.querySelector('#portal-attractor');
  2985.  
  2986. if (!this.battleButton){
  2987. return;
  2988. }
  2989. this.advantageSpan = this.battleButton.parentElement;
  2990. if (!this.hireButton){
  2991. return;
  2992. }
  2993. this.hireSpan = this.hireButton.parentElement;
  2994. }
  2995.  
  2996. autoBattle() {
  2997. if(researched('tech-fort')) {
  2998. const fort = $('#fort .current');
  2999. let have = parseInt(fort[0].innerText);
  3000. let patrols = parseInt(fort[1].innerText);
  3001. let size = parseInt(fort[2].innerText);
  3002. if (this.addToFortress){
  3003. this.addToFortress.click();
  3004. }
  3005. let turret = $('#portal-turret');
  3006. let count = parseInt(turret.find('.count')[0].innerText);
  3007. let on = turret.find('.on');
  3008. let onCount = parseInt(on[0].innerText);
  3009. if(patrols == 0){
  3010. // shut off turrets to freeze invasions
  3011. let off = turret.find('.off');
  3012. let offCount = parseInt(off[0].innerText);
  3013. count = count - offCount;
  3014. while(count--){
  3015. off.click();
  3016. }
  3017. }else if(onCount < count){
  3018. // turn turrets back on
  3019. count = count - onCount;
  3020. while(count--){
  3021. on.click();
  3022. }
  3023. }
  3024.  
  3025. if (have >= size && this.addToPatrols){
  3026. this.addToPatrols.click();
  3027. }
  3028. if (this.attractor){
  3029. let danger = parseInt($('#fort span')[1].dataset.label);
  3030. const attractor = $('#portal-attractor');
  3031. let count = parseInt(attractor.find('.count')[0].innerText);
  3032. let on = parseInt(attractor.find('.on')[0].innerText);
  3033. if (danger < 1600){
  3034. count = count - on;
  3035. while(count--){
  3036. attractor.find('.on').click();
  3037. }
  3038. }else if(on > 0){
  3039. while(on--){
  3040. attractor.find('.off').click();
  3041. }
  3042. }
  3043. }
  3044. }
  3045. if (!this.battleButton) {
  3046. return;
  3047. }
  3048. // Don't battle if the garrison hasn't been unlocked
  3049. if (!researched('tech-garrison')) {return;}
  3050. // Don't battle after unification
  3051. if (researched('tech-wc_conquest')||researched('tech-wc_morale')||researched('tech-wc_money')||researched('tech-wc_reject')) {return;}
  3052. // Adding soldiers
  3053. for (let i = 0;i < this.soldierCount[0] - parseInt(this.armySize.innerText);i++) {
  3054. this.addBattalion.click();
  3055. }
  3056. // Mercs
  3057. let label = this.hireSpan.dataset.label;
  3058. if (parseInt(label.match(/\d+/)) < 1000){
  3059. this.hireButton.click();
  3060. }
  3061.  
  3062. // If no wounded and max soldiers, start battle
  3063. if (this.woundedCount == 0 && this.soldierCount[0] / this.soldierCount[1] > .9 && this.soldierCount[0] != 0) {
  3064. //console.log("Wounded: ", this.woundedCount, "Soldiers: ", this.soldierCount);
  3065. // Changing campaign to match current rating
  3066. for (let i = 0;i < 4;i++) {
  3067. this.lowerCampaign.click();
  3068. }
  3069. for (let i = 1;i <= 4;i++) {
  3070. //console.log(this.rating, "VS", this.campaignStrengths[i]);
  3071. if (this.rating < this.campaignStrengths[i].rating) {
  3072. break;
  3073. } else {
  3074. this.higherCampaign.click();
  3075. }
  3076. }
  3077. // Don't battle if army rating lower than lowest campaign
  3078. if (this.rating < this.campaignStrengths[0].rating) {return;}
  3079. // Starting battle
  3080. const battle = () => {
  3081. const label = this.advantageSpan.dataset.label;
  3082. if(label.indexOf('disadvantage') == -1 && parseInt(label) >= 30){
  3083. this.battleButton.click();
  3084. }else {
  3085. clearInterval(timer);
  3086. }
  3087. }
  3088. let timer = setInterval(battle, 1000);
  3089. }
  3090. }
  3091.  
  3092. get soldierCount() {
  3093. return document.querySelector('#garrison .barracks > span:nth-child(2)').innerText.split(' / ');
  3094. }
  3095.  
  3096. get woundedCount() {
  3097. return document.querySelector('#garrison .barracks:nth-child(2) > span:nth-child(2)').innerText;
  3098. }
  3099.  
  3100. get rating() {
  3101. return document.querySelector('#garrison > .header').children[1].children[1].childNodes[0].textContent;
  3102. }
  3103. }
  3104. let autoBattler = new AutoBattler();
  3105.  
  3106. function prioCompare(a, b) {
  3107. return b.priority - a.priority;
  3108. }
  3109. class AutoEmployer {
  3110.  
  3111. autoEmploy() {
  3112. // only run every 10sec
  3113. if (count % 10 != 0){
  3114. return;
  3115. }
  3116. // Sorting based on priority
  3117. let sortedJobs = [];
  3118. let x;
  3119. for (x in jobs) {
  3120. if (jobs[x].unlocked) {
  3121. sortedJobs.push(jobs[x]);
  3122. }
  3123. }
  3124. sortedJobs.sort(prioCompare);
  3125. let free_agents = 0;
  3126. let total_priority = 0;
  3127. // Find total free agents
  3128. for (let i = 0;i < sortedJobs.length;i++) {
  3129. let job = sortedJobs[i];
  3130. // Free agents are determined by the ratio of priority
  3131. // Priority 9 would have a ratio of 9/9, thus will always have no free agents
  3132. // Priority 0 would have a ratio of 0/9, thus always will have free agents
  3133.  
  3134. //console.log("Checking", job.name);
  3135. // If Craftsman, move all workers to Plywood for reassignment
  3136. /*
  3137. if (job.id == "craftsman") {
  3138. for (x in craftJobs) {
  3139. let cjob = craftJobs[x];
  3140. if (!cjob.unlocked) {continue;}
  3141. for (let k = 0;k < cjob.employed;k++) {
  3142. cjob.fireBtn.click();
  3143. craftJobs.Plywood.hireBtn.click();
  3144. }
  3145. }
  3146. }
  3147. */
  3148.  
  3149. total_priority += job.priority;
  3150. // Job has no max employees (Unemployed, Farmer, Lumberjack, Quarry Worker)
  3151. // Use the one more than the current employed
  3152. let maxEmployed = (job.maxEmployed == -1) ? job.employed + 5 : job.maxEmployed;
  3153. job.max_employed = maxEmployed;
  3154. job.wanted = Math.round(maxEmployed /(1+Math.pow(Math.E, -job.priority+4.5)));
  3155. job.need = job.wanted - job.employed;
  3156. job.temp_employed = job.employed;
  3157. //console.log(element.name, element.wanted, element.need);
  3158. // If there is negative need, send to unemployed
  3159. if (job.need < 0) {
  3160. // Removal from craftsman requires additional work
  3161. if (job.id == 'craftsman') {
  3162. let totalRemove = -job.need;
  3163. // Searching through craft jobs to remove
  3164. for (x in craftJobs) {
  3165. if (!craftJobs[x].unlocked) {continue;}
  3166. craftJobs[x].temp_employed = craftJobs[x].employed;
  3167. if (craftJobs[x].employed >= totalRemove) {
  3168. for (let j = 0;j < totalRemove;j++) {
  3169. craftJobs[x].fire();
  3170. }
  3171. craftJobs[x].temp_employed = craftJobs[x].employed - totalRemove;
  3172. free_agents += totalRemove;
  3173. break;
  3174. } else {
  3175. for (let j = 0;j < craftJobs[x].employed;j++) {
  3176. craftJobs[x].fire();
  3177. }
  3178. craftJobs[x].temp_employed = 0;
  3179. free_agents += craftJobs[x].employed;
  3180. totalRemove -= craftJobs[x].employed;
  3181. }
  3182. }
  3183. } else {
  3184. for (let j = 0;j < -job.need;j++) {
  3185. if (job.id != 'free') {
  3186. job.fire();
  3187. }
  3188. job.temp_employed -= 1;
  3189. free_agents += 1;
  3190. }
  3191. }
  3192. }
  3193. }
  3194.  
  3195. //console.log("Finished freeing agents");
  3196.  
  3197. // All free agents should be in unemployed
  3198. // Now send those back that are needed
  3199. for (let i = 0;i < sortedJobs.length;i++) {
  3200. let job = sortedJobs[i];
  3201. for (let i = 0;i < job.need;i++) {
  3202. job.hire();
  3203. job.temp_employed += 1;
  3204. free_agents -= 1;
  3205. }
  3206. }
  3207.  
  3208. //console.log("Finished sending initial agents");
  3209.  
  3210. // Divy up the remaining free agents based on priority
  3211. // The pie is split based on total priority points
  3212. for (let i = 0;i < sortedJobs.length;i++) {
  3213. let job = sortedJobs[i];
  3214. if (job.id == "free") {continue;}
  3215. //console.log("Sending secondary agents", job.name);
  3216. let pie = Math.round(free_agents * job.priority / total_priority);
  3217. for (let j = 0;j < Math.min(pie, job.max_employed - job.temp_employed);j++) {
  3218. job.hire();
  3219. free_agents -= 1;
  3220. }
  3221. total_priority -= job.priority;
  3222. }
  3223.  
  3224. // Divy up Craftsmen
  3225.  
  3226. if (!jobs.craftsman.unlocked) {return;}
  3227. //console.log("Divying up Craftsman");
  3228. // Delay to get new craftman number
  3229. setTimeout(function() {
  3230. let totalCraftsman = 0;
  3231. let total_priority = 0;
  3232. for (x in craftJobs) {
  3233. let cjob = craftJobs[x];
  3234. if (!cjob.unlocked) {continue;}
  3235. total_priority += cjob.priority;
  3236. totalCraftsman += cjob.employed;
  3237. }
  3238. for (x in craftJobs) {
  3239. let cjob = craftJobs[x];
  3240. if (!cjob.unlocked) {continue;}
  3241. cjob.want = Math.ceil(totalCraftsman * cjob.priority / total_priority)
  3242. cjob.need = cjob.want - cjob.employed;
  3243. if (cjob.need < 0) {
  3244. for (let j = 0;j < -cjob.need;j++) {
  3245. cjob.fire();
  3246. }
  3247. }else if(cjob.need > 0){
  3248. for (let j = 0;j < cjob.need;j++) {
  3249. cjob.hire();
  3250. }
  3251. }
  3252. }
  3253. // for (x in craftJobs) {
  3254. // let cjob = craftJobs[x];
  3255. // if (!cjob.unlocked) {continue;}
  3256. // if (cjob.need > 0) {
  3257. // for (let j = 0;j < cjob.need;j++) {
  3258. // cjob.hire();
  3259. // }
  3260. // }
  3261. // }
  3262. }, 25);
  3263. }
  3264.  
  3265. lowerPriority(job) {
  3266. job.lowerPriority();
  3267. this.updateUI();
  3268. }
  3269.  
  3270. higherPriority(job) {
  3271. job.higherPriority();
  3272. this.updateUI();
  3273. }
  3274.  
  3275. updateUI() {
  3276. let x;
  3277. for (x in jobs) {
  3278. let job = jobs[x];
  3279. if (job.id == "free" && job.name != 'Hunter') {continue;}
  3280. if (!job.unlocked) {continue;}
  3281. let count;
  3282. if (job.id == "craftsman") {
  3283. count = $('#foundry > .job > .foundry.controls > .count')[0];
  3284. } else {
  3285. count = $('#civ-'+job.id+' > .ea-employ-settings > .count')[0];
  3286. }
  3287. count.removeChild(count.firstChild);
  3288. count.appendChild(document.createTextNode(job.priority));
  3289. }
  3290. for (x in craftJobs) {
  3291. let cjob = craftJobs[x];
  3292. if (!cjob.unlocked) {continue;}
  3293. let count = $('#craft'+cjob.id).parent().children()[2].children[1];
  3294. count.removeChild(count.firstChild);
  3295. count.appendChild(document.createTextNode(cjob.priority));
  3296. }
  3297. }
  3298. }
  3299. let autoEmployer = new AutoEmployer();
  3300.  
  3301. let moraleLabel = $('#morale').children(1)[0];
  3302. let incTaxBtn = $('#tax_rates > .add');
  3303. let decTaxBtn = $('#tax_rates > .sub');
  3304. function autoTax() {
  3305. // Don't start taxes if haven't researched
  3306. if (!researched('tech-tax_rates')) {return;}
  3307. let morale = parseInt(moraleLabel.innerText.substr(0,moraleLabel.innerText.length-1));
  3308. if (morale > settings.defaultMorale) {
  3309. for (let i = 0;i < morale - settings.defaultMorale;i++) {
  3310. incTaxBtn.click();
  3311. }
  3312. } else {
  3313. for (let i = 0;i < settings.defaultMorale - morale;i++) {
  3314. decTaxBtn.click();
  3315. }
  3316. }
  3317. }
  3318. function shuffle(array) {
  3319. array.sort(() => Math.random() - 0.5);
  3320. }
  3321. function autoMarket(bulkSell, ignoreSellRatio) {
  3322. // Don't start autoMarket if haven't unlocked market
  3323. if (!researched('tech-market')) {return;}
  3324. let curMoney = resources.Money.amount;
  3325. let maxMoney = resources.Money.storage;
  3326. let multipliers = $('#market-qty').children();
  3327. // If multipliers don't exist (aka cannot manual buy/sell) don't autoMarket
  3328. if (multipliers === null || multipliers === undefined) {return;}
  3329. let inputs = $(multipliers[2]).find('input');
  3330.  
  3331. // no market challenge
  3332. if(!inputs.length) return;
  3333.  
  3334. if(!$(multipliers[2]).find('input')[0].checked){
  3335. multipliers[2].click();
  3336. }
  3337. let qty = 25;
  3338. setTimeout(function(){ //timeout needed to let the click on multiplier take effect
  3339. if (count % 10 == 0){
  3340. shuffle(resourcesArr);
  3341. }
  3342. resourcesArr.forEach((x) => {
  3343. let resource = resources[x];
  3344. // Continue if resource hasn't been unlocked
  3345. if(!resource.unlocked) {return;}
  3346.  
  3347. //console.log("Auto Market", x);
  3348. let curResource = resource.amount;
  3349. let maxResource = resource.storage;
  3350. // Can sell resource
  3351. //console.log(resource.autoSell, resource.ratio, resource.sellRatio);
  3352. if (resource.autoSell && resource.ratio > resource.sellRatio) {
  3353. //console.log("Autoselling", resource.name);
  3354. let sellValue = getRealValue(resource.sellBtn.innerHTML.substr(1));
  3355. let counter = 0;
  3356. //console.log("CURM:", curMoney, "sellV", sellValue, "MAXM", maxMoney, "CURR", curResource, "MAXR", maxResource);
  3357. while(true) {
  3358. // Break if too much money, not enough resources, or sell ratio reached
  3359. if (curMoney + sellValue >= maxMoney || curResource - qty <= 0 || curResource / maxResource < resource.sellRatio) {
  3360. //console.log("Sold", counter*100);
  3361. break;
  3362. }
  3363. counter += 1;
  3364. resource.sellBtn.click();
  3365. curMoney += sellValue;
  3366. curResource -= qty;
  3367. }
  3368. }
  3369.  
  3370. if(bulkSell === true) {
  3371. return;
  3372. }
  3373. //console.log(resource.autoBuy, resource.ratio, resource.buyRatio);
  3374. if (resource.autoBuy && resource.ratio < resource.buyRatio) {
  3375. let buyValue = getRealValue(resource.buyBtn.innerHTML.substr(1));
  3376. //console.log("CURM:", curMoney, "sellV", buyValue, "MAXM", maxMoney, "CURR", curResource, "MAXR", maxResource, "MINM", getMinMoney());
  3377. while(true) {
  3378. // Break if too little money, too much resources, or buy ratio reached
  3379. if (curMoney - buyValue < getMinMoney() || curResource + qty > resource.storage || curResource / maxResource > resource.buyRatio) {
  3380. break;
  3381. }
  3382. resource.buyBtn.click();
  3383. curMoney -= buyValue;
  3384. curResource += qty;
  3385. }
  3386. }
  3387. });
  3388. }, 25);
  3389. }
  3390.  
  3391. function autoBuild(){
  3392. for (let x in buildings) {
  3393. let building = buildings[x];
  3394. if (!building.unlocked) {
  3395. continue;
  3396. }
  3397. if (building.limit != -1 && building.numTotal >= building.limit) {
  3398. continue;
  3399. }
  3400. let btn = document.getElementById(building.id);
  3401. if (building.enabled && btn.className.indexOf('cna') < 0) {
  3402. btn.getElementsByTagName("a")[0].click();
  3403. if (settings.autoPrint){messageQueue("[AUTO-BUILD] " + btn.getElementsByTagName("a")[0].children[0].innerText, 'dark');}
  3404. return;
  3405. }
  3406. }
  3407. }
  3408.  
  3409. function autoFactory() {
  3410. if (!researched('tech-industrialization')) {return;}
  3411. let factory = unsafeWindow.vars.global.city.factory;
  3412. let res = unsafeWindow.vars.global.resource;
  3413.  
  3414. let div = 0;
  3415. div += researched('tech-industrialization') ? 1 : 0;
  3416. div += researched('tech-polymer') ? 1 : 0;
  3417. div += researched('tech-nano_tubes') ? 1 : 0;
  3418. div += researched('tech-stanene') ? 1 : 0;
  3419.  
  3420. let per = parseInt(factory.count / div);
  3421. let overflow = factory.count % div;
  3422. factory.Alloy = per + overflow;
  3423.  
  3424. if(!researched('tech-polymer')) return;
  3425. factory.Polymer = per;
  3426.  
  3427. if(!researched('tech-nano_tubes')) return;
  3428. factory.Nano = per;
  3429.  
  3430. if(!researched('tech-stanene')) return;
  3431. factory.Stanene = per;
  3432. }
  3433.  
  3434. function autoSmelter(limits) {
  3435. if (!researched('tech-steel')) {return;}
  3436.  
  3437. if(!limits){
  3438. let limits = [];
  3439. limits.Oil = null;
  3440. limits.Coal = null;
  3441. limits.Iron = null;
  3442. limits.Steel = null;
  3443. }
  3444. let smelter = unsafeWindow.vars.global.city.smelter;
  3445. let res = unsafeWindow.vars.global.resource;
  3446. let total = smelter.count;
  3447.  
  3448. smelter.Iron = 0;
  3449. smelter.Steel = total;
  3450. smelter.Wood = 0;
  3451. smelter.Coal = 0;
  3452. smelter.Oil = 0;
  3453.  
  3454. let incrAndCheck = (part, check, diff, max) => {
  3455. if(!max) return 0;
  3456. smelter[part] = 0;
  3457. let currDiff = res[check].diff;
  3458. while(smelter[part] < max){
  3459. if((currDiff - diff) >= 0){
  3460. currDiff -= diff;
  3461. smelter[part] += 1;
  3462. }else{
  3463. break;
  3464. }
  3465. }
  3466. return max - smelter[part];
  3467. }
  3468.  
  3469. let left = total;
  3470. if(researched('tech-oil_well')){
  3471. left = incrAndCheck('Oil', 'Oil', .35, left);
  3472. }
  3473. if(researched('tech-coal_mining')){
  3474. left = incrAndCheck('Coal', 'Coal', .25, left);
  3475. }
  3476. smelter.Wood = left;
  3477.  
  3478. return;
  3479. if(smelter.Steel){
  3480. smelter.Steel = 0;
  3481. while(smelter.Steel < total){
  3482. smelter.Steel += 1;
  3483. if(res.Iron.diff < 0){
  3484. smelter.Steel -= 1;
  3485. break;
  3486. }
  3487. }
  3488. }
  3489. smelter.Iron = total - smelter.Steel;
  3490. if(researched('tech-oil_well')){
  3491.  
  3492. }
  3493. if(researched('tech-coal_mining')){
  3494. }
  3495.  
  3496. // Checking if modal already open
  3497. if ($('.modal').length != 0) {
  3498. // Closing modal
  3499. let closeBtn = $('.modal-close')[0];
  3500. if (closeBtn !== undefined) {closeBtn.click();}
  3501. return;
  3502. }
  3503. // Ensuring no modal conflicts
  3504. if (modal) {return;}
  3505. modal = true;
  3506.  
  3507. resources.Oil.temp_rate = resources.Oil.rate;
  3508. resources.Iron.temp_rate = resources.Iron.rate;
  3509. resources.Lumber.temp_rate = resources.Lumber.rate;
  3510. resources.Coal.temp_rate = resources.Coal.rate;
  3511. resources.Steel.temp_rate = resources.Steel.rate;
  3512.  
  3513. console.log("Auto Smelting");
  3514. // Opening modal
  3515. $('#city-smelter > .special').click();
  3516. // Delaying for modal animation
  3517. setTimeout(function() {
  3518. // Finding relevent elements
  3519. let decBtns = $('#specialModal > div:nth-child(2) > .sub');
  3520. let incBtns = $('#specialModal > div:nth-child(2) > .add');
  3521. let labels = $('#specialModal > div:nth-child(2) > span > .current');
  3522. let lumberInc = null; let lumberDec = null;
  3523. let coalInc = null; let coalDec = null;
  3524. let oilInc = null; let oilDec = null;
  3525. let lumberNum = null; let coalNum = null; let oilNum = null;
  3526. let lumberFuel = null; let coalFuel = null; let oilFuel = null;
  3527. // Determining which fuel types are available
  3528. if (decBtns.length == 2) {
  3529. // Only two buttons. Either Ent type race with Coal/Oil, or haven't unlocked oil yet
  3530. if (!resources.Oil.unlocked) {
  3531. // Oil not unlocked, thus two buttons mean Lumber/Coal
  3532. lumberInc = incBtns[0];
  3533. lumberDec = decBtns[0];
  3534. let temp = labels[0].attributes[0].value;
  3535. lumberFuel = parseFloat(/Consume ([\d\.]+).*/.exec(temp)[1]);
  3536. lumberNum = parseInt(/Lumber ([\d]+)/.exec(labels[0].innerText)[1]);
  3537. coalInc = incBtns[1];
  3538. coalDec = decBtns[1];
  3539. temp = labels[1].attributes[0].value;
  3540. coalFuel = parseFloat(/Burn ([\d\.]+).*/.exec(temp)[1]);
  3541. coalNum = parseInt(/Coal ([\d]+)/.exec(labels[1].innerText)[1]);
  3542. } else {
  3543. // Must be Ent type race with Coal/Oil
  3544. coalInc = incBtns[0];
  3545. coalDec = decBtns[0];
  3546. let temp = labels[0].attributes[0].value;
  3547. coalFuel = parseFloat(/Burn ([\d\.]+).*/.exec(temp)[1]);
  3548. coalNum = parseInt(/Coal ([\d]+)/.exec(labels[0].innerText)[1]);
  3549. oilInc = incBtns[1];
  3550. oilDec = decBtns[1];
  3551. temp = labels[1].attributes[0].value;
  3552. oilFuel = parseFloat(/Burn ([\d\.]+).*/.exec(temp)[1]);
  3553. oilNum = parseInt(/Oil ([\d]+)/.exec(labels[1].innerText)[1]);
  3554. }
  3555. } else {
  3556. // Three buttons means all fuels unlocked
  3557. lumberInc = incBtns[0];
  3558. lumberDec = decBtns[0];
  3559. let temp = labels[0].attributes[0].value;
  3560. lumberFuel = parseFloat(/Consume ([\d\.]+).*/.exec(temp)[1]);
  3561. lumberNum = parseInt(/Lumber ([\d]+)/.exec(labels[0].innerText)[1]);
  3562. coalInc = incBtns[1];
  3563. coalDec = decBtns[1];
  3564. temp = labels[1].attributes[0].value;
  3565. coalFuel = parseFloat(/Burn ([\d\.]+).*/.exec(temp)[1]);
  3566. coalNum = parseInt(/Coal ([\d]+)/.exec(labels[1].innerText)[1]);
  3567. oilInc = incBtns[2];
  3568. oilDec = decBtns[2];
  3569. temp = labels[2].attributes[0].value;
  3570. oilFuel = parseFloat(/Burn ([\d\.]+).*/.exec(temp)[1]);
  3571. oilNum = parseInt(/Oil ([\d]+)/.exec(labels[2].innerText)[1]);
  3572. }
  3573. console.log("L", lumberNum, lumberFuel, "C", coalNum, coalFuel, "O", oilNum, oilFuel);
  3574. if (lumberNum !== null) {resources.Lumber.temp_rate += lumberFuel * lumberNum;}
  3575. if (coalNum !== null) {resources.Coal.temp_rate += coalFuel * coalNum;}
  3576. if (oilNum !== null) {resources.Oil.temp_rate += oilFuel * oilNum;}
  3577. // Finding iron/steel buttons
  3578. let ironBtn = $('#specialModal .smelting button')[0];
  3579. let steelBtn = $('#specialModal .smelting button')[1];
  3580. let ironNum = ironBtn.innerText;
  3581. let steelNum = steelBtn.innerText;
  3582. ironNum = parseInt(/Iron Smelting: ([\d]+)/.exec(ironNum)[1]);
  3583. steelNum = parseInt(/Steel Smelting: ([\d]+)/.exec(steelNum)[1]);
  3584. let ironVal = ironBtn.attributes[0].value;
  3585. let steelVal = steelBtn.attributes[0].value;
  3586. let ironPercent = parseInt(/[^\d]+([\d]+)%/.exec(ironVal)[1]);
  3587. let temp = /[^\d\.]*([\d\.]+)[^\d\.]*([\d\.]+)[^\d\.]*([\d\.]+)[^\d\.]*/.exec(steelVal);
  3588. let steelCoalFuel = parseFloat(temp[1]);
  3589. let steelIronFuel = parseFloat(temp[2]);;
  3590. let steelProduce = parseFloat(temp[3]);;
  3591. console.log("Iron", ironNum, ironPercent, "Steel", steelNum, steelIronFuel, steelCoalFuel, steelProduce);
  3592. resources.Iron.temp_rate += steelIronFuel * steelNum;
  3593. resources.Coal.temp_rate += steelCoalFuel * steelNum;
  3594. resources.Steel.temp_rate -= steelProduce * steelNum;
  3595. resources.Iron.temp_rate /= (1 + ironPercent*ironNum / 100);
  3596. // Calculating changes
  3597. let totalSmelters = buildings['city-smelter'].numTotal;
  3598. let wantedIron = 0;
  3599. let wantedSteel = 0;
  3600. if (!limits || limits.Iron === null) {
  3601. // Does not require iron, max out steel regardless
  3602. wantedSteel = totalSmelters;
  3603. } else {
  3604. if (limits.Steel !== null) {
  3605. // Requires both, find ratio
  3606. wantedIron = Math.floor(limits.Iron.priority / (limits.Iron.priority + limits.Steel.priority));
  3607. wantedSteel = totalSmelters - wantedIron;
  3608. } else {
  3609. // Requires only iron, max out
  3610. wantedIron = totalSmelters;
  3611. }
  3612. }
  3613. // Calculating Fuel
  3614. let wantedLumber = 0;
  3615. let wantedCoal = 0;
  3616. let wantedOil = 0;
  3617. let wantedTotal = totalSmelters;
  3618. // Oil unlocked and not needed
  3619. if (!limits || limits.Oil === null && oilInc !== null) {
  3620. wantedOil = Math.floor(resources.Oil.temp_rate / oilFuel);
  3621. wantedOil = (wantedOil > wantedTotal) ? wantedTotal : wantedOil;
  3622. wantedTotal -= wantedOil;
  3623. }
  3624. console.log(totalSmelters, wantedTotal, wantedOil);
  3625. // Coal unlocked and not needed
  3626. if (!limits || limits.Coal === null && coalInc !== null) {
  3627. // If Ent type race, fill rest with coal
  3628. if (lumberInc === null) {
  3629. wantedCoal = wantedTotal;
  3630. } else {
  3631. wantedCoal = Math.floor(resources.Coal.temp_rate / coalFuel);
  3632. wantedCoal = (wantedCoal > wantedTotal) ? wantedTotal : wantedCoal;
  3633. wantedTotal -= wantedCoal;
  3634. }
  3635. }
  3636. // Fill the rest with lumber
  3637. if (lumberInc !== null) {
  3638. wantedLumber = wantedTotal;
  3639. }
  3640.  
  3641. console.log("L", wantedLumber, "C", wantedCoal, "O", wantedOil, "I", wantedIron,"S", wantedSteel);
  3642. let pos_coal_rate = resources.Coal.temp_rate - wantedCoal*coalFuel - wantedSteel*steelCoalFuel;
  3643. while(pos_coal_rate < 0) {
  3644. console.log("L", wantedLumber, "C", wantedCoal, "O", wantedOil, "I", wantedIron,"S", wantedSteel, "CR", pos_coal_rate);
  3645. // Try getting rid of coal
  3646. if (wantedCoal > 0) {
  3647. wantedCoal -= 1;
  3648. if (lumberInc !== null) {
  3649. // Put into lumber if exists
  3650. wantedLumber += 1;
  3651. } else {
  3652. // Nothing to put into, get rid of one
  3653. if (wantedSteel > 0) {
  3654. wantedSteel -= 1;
  3655. } else {
  3656. wantedIron -= 1;
  3657. }
  3658. }
  3659. } else if (wantedSteel > 0) {
  3660. wantedSteel -= 1;
  3661. wantedIron += 1;
  3662. } else {
  3663. break;
  3664. }
  3665. pos_coal_rate = resources.Coal.temp_rate - wantedCoal*coalFuel - wantedSteel*steelCoalFuel;
  3666. }
  3667. let pos_iron_rate = resources.Iron.temp_rate * (1 + ironPercent*wantedIron / 100) - wantedSteel*steelIronFuel;
  3668. while(pos_iron_rate < 0) {
  3669. console.log("L", wantedLumber, "C", wantedCoal, "O", wantedOil, "I", wantedIron,"S", wantedSteel, "IR", pos_iron_rate);
  3670. // Get rid of some steel
  3671. if (wantedSteel > 0) {
  3672. wantedSteel -= 1;
  3673. wantedIron += 1;
  3674. } else {
  3675. break;
  3676. }
  3677. pos_iron_rate = resources.Iron.temp_rate * (1 + ironPercent*wantedIron / 100) - wantedSteel*steelIronFuel;
  3678. }
  3679. console.log("L", wantedLumber, "C", wantedCoal, "O", wantedOil, "I", wantedIron,"S", wantedSteel);
  3680.  
  3681. smelter.Iron = wantedIron;
  3682. smelter.Steel = wantedSteel;
  3683.  
  3684. smelter.Lumber = wantedLumber || 0;
  3685. smelter.Coal = wantedCoal || 0;
  3686. smelter.Oil = wantedOil || 0;
  3687. // Closing modal
  3688. let closeBtn = $('.modal-close')[0];
  3689. if (closeBtn !== undefined) {closeBtn.click();}
  3690. modal = false;
  3691. }, 100);
  3692. }
  3693.  
  3694. function autoSupport() {
  3695. // Don't start autoSupport if haven't unlocked power
  3696. if (!researched('tech-electricity')) {return;}
  3697. let x;
  3698. // Generating unlocked producers and consumers
  3699. let ps = [];
  3700. let cs = [];
  3701. for (x in elecProducers) {
  3702. if (elecProducers[x].unlocked) {
  3703. ps.push(elecProducers[x]);
  3704. }
  3705. }
  3706. for (x in elecConsumers) {
  3707. if (elecConsumers[x].unlocked) {
  3708. cs.push(elecConsumers[x]);
  3709. }
  3710. }
  3711. cs.sort(prioCompare);
  3712. //console.log(ps, cs);
  3713. // Turn on all possible producers
  3714. for (let i = 0;i < ps.length;i++) {
  3715. let p = ps[i];
  3716. p.delta = 0;
  3717. // Calculate whether to turn off
  3718. let needTurnOff = false;
  3719. for (let j = 0;j < p.consume.length;j++) {
  3720. let res = p.consume[j].res;
  3721. if (res.rate < 0) {
  3722. needTurnOff = true;
  3723. }
  3724. }
  3725. // A resource that this producer needs is decreasing
  3726. if (needTurnOff && p.numOn > 0) {
  3727. p.decBtn.click();
  3728. p.delta = -1;
  3729. continue;
  3730. }
  3731. // Calculate whether to turn on
  3732. let canTurnOn = true;
  3733. for (let j = 0;j < p.consume.length;j++) {
  3734. let res = p.consume[j].res;
  3735. let cost = p.consume[j].cost;
  3736. if (res.rate < cost) {
  3737. canTurnOn = false;
  3738. }
  3739. }
  3740. if (canTurnOn && p.numOn < p.numTotal) {
  3741. p.incBtn.click();
  3742. p.delta = 1;
  3743. }
  3744. }
  3745. // Calculate total possible power
  3746. let totalPower = 0;
  3747. for (let i = 0;i < ps.length;i++) {
  3748. let p = ps[i];
  3749. totalPower += p.produce * (p.numOn + p.delta)
  3750. }
  3751. //console.log("Total Power:", totalPower);
  3752. // Distribute power to needed buildings
  3753. for (let i = 0;i < cs.length;i++) {
  3754. let c = cs[i];
  3755. // Have some power left to give
  3756. if (totalPower > 0) {
  3757. let canTurnOn = (totalPower - (totalPower % c.consume)) / c.consume;
  3758. canTurnOn = Math.min(canTurnOn, c.numTotal);
  3759. if (c.numOn > canTurnOn) {
  3760. for (let j = 0;j < c.numOn - canTurnOn;j++) {
  3761. c.decBtn.click();
  3762. }
  3763. } else {
  3764. for (let j = 0;j < canTurnOn - c.numOn;j++) {
  3765. c.incBtn.click();
  3766. }
  3767. }
  3768. totalPower -= canTurnOn * c.consume;
  3769. //console.log(c, canTurnOn);
  3770. // Run out of power
  3771. } else {
  3772. for (let j = 0;j < c.numOn;j++) {
  3773. c.decBtn.click();
  3774. }
  3775. //console.log(c, 0);
  3776. }
  3777. }
  3778. }
  3779.  
  3780. function autoResearch(){
  3781. let items = document.querySelectorAll('#tech .action');
  3782. for(let i = 0; i < items.length; i++){
  3783. if(items[i].className.indexOf("cna") < 0){
  3784. // Skip blackhole, TODO add to setting choices
  3785. if(items[i].id == "tech-exotic_infusion" || items[i].id == "tech-stabilize_blackhole"){continue;}
  3786. // Checking if fanaticism or anthropology
  3787. if(items[i].id == "tech-fanaticism" && settings.fanORanth == "anthropology") {continue;}
  3788. if(items[i].id == "tech-anthropology" && settings.fanORanth == "fanaticism") {continue;}
  3789. // Checking if study/deify ancients
  3790. if(items[i].id == "tech-study" && settings.studyORdeify == "deify") {continue;}
  3791. if(items[i].id == "tech-deify" && settings.studyORdeify == "study") {continue;}
  3792. // Checking if unification
  3793. if(items[i].id.indexOf("wc") >= 0 && items[i].id != "tech-wc_"+settings.uniChoice) {continue;}
  3794. items[i].children[0].click();
  3795. if(items[i].id.indexOf("wc") >= 0) {continue;}
  3796. if(settings.autoPrint){messageQueue("[AUTO-RESEARCH] " + items[i].children[0].children[0].innerText,'dark');}
  3797. setTimeout(resetUI, 2000);
  3798. return;
  3799. }
  3800. }
  3801. }
  3802.  
  3803. function getAvailableBuildings() {
  3804. let build = [];
  3805. for (let x in buildings) {
  3806. // Don't check buildings that aren't unlocked
  3807. if (!buildings[x].unlocked) {continue;}
  3808. // Don't check buildings that aren't enabled
  3809. if (!buildings[x].enabled) {continue;}
  3810. // Don't check buildings that met their limit
  3811. if (buildings[x].limit != -1 && buildings[x].numTotal >= buildings[x].limit) {continue;}
  3812. // Don't check buildings that can't be bought
  3813. let btn = document.getElementById(buildings[x].id);
  3814. if (btn.className.indexOf('cnam') >= 0) {continue;}
  3815. build.push(buildings[x]);
  3816. }
  3817. //console.log(build);
  3818. return build;
  3819. }
  3820. function getAvailableResearches() {
  3821. let research = [];
  3822. for (let x in researches) {
  3823. // Don't check researches that aren't unlocked
  3824. if (!researches[x].unlocked) {continue;}
  3825. // Don't check researches that have already been researched
  3826. if (researches[x].researched) {continue;}
  3827. // Don't check researches that can't be bought
  3828. let btn = document.getElementById(researches[x].id);
  3829. if (btn.className.indexOf('cnam') >= 0) {continue;}
  3830. // Research filters
  3831. if(researches[x].id == "tech-fanaticism" && settings.fanORanth == "anthropology") {continue;}
  3832. if(researches[x].id == "tech-anthropology" && settings.fanORanth == "fanaticism") {continue;}
  3833. // Checking if study/deify ancients
  3834. if(researches[x].id == "tech-study" && settings.studyORdeify == "deify") {continue;}
  3835. if(researches[x].id == "tech-deify" && settings.studyORdeify == "study") {continue;}
  3836. // Checking if unification
  3837. if(researches[x].id.indexOf("wc") >= 0 && researches[x].id != "tech-wc_"+settings.uniChoice) {continue;}
  3838. research.push(researches[x]);
  3839. }
  3840. //console.log(research);
  3841. return research;
  3842. }
  3843. function getAvailableArpas() {
  3844. let arpa = [];
  3845. for (let x in arpas) {
  3846. // Don't add ARPAs that are not unlocked
  3847. if (!arpas[x].unlocked) {continue;}
  3848. // Don't add ARPAs that are not enabled
  3849. if (!arpas[x].enabled) {continue;}
  3850. arpa.push(arpas[x]);
  3851. }
  3852. return arpa;
  3853. }
  3854. function getAvailableStorages() {
  3855. let store = [];
  3856. for (let x in storages) {
  3857. // Don't add if not unlocked
  3858. if (!storages[x].unlocked) {continue;}
  3859. // Don't add if no more space
  3860. if (storages[x].full) {continue;}
  3861. store.push(storages[x]);
  3862. }
  3863. return store;
  3864. }
  3865. function getAvailableActions() {
  3866. // Getting buildings and researches
  3867. let actions = getAvailableBuildings().concat(getAvailableResearches()).concat(getAvailableArpas()).concat(getAvailableStorages());
  3868.  
  3869. for (let i = 0;i < actions.length;i++) {
  3870. actions[i].completion = {};
  3871. actions[i].completionTime = {};
  3872. actions[i].maxCompletionTime = 0;
  3873. actions[i].limitingRes = null;
  3874. actions[i].keptRes = {};
  3875. }
  3876. return actions;
  3877. }
  3878. function getAvailableResources() {
  3879. let res = [];
  3880. for (let x in resources) {
  3881. // Don't check resources that aren't unlocked
  3882. if (!resources[x].unlocked) {continue;}
  3883. res.push(resources[x]);
  3884. }
  3885. for (let x in craftableResources) {
  3886. // Don't check resources that aren't unlocked
  3887. if (!craftableResources[x].unlocked) {continue;}
  3888. res.push(craftableResources[x]);
  3889. }
  3890. console.log(res);
  3891. return res;
  3892. }
  3893. function autoPrioritize(count) {
  3894. // Finding available actions
  3895. let actions = getAvailableActions();
  3896. //console.log(actions);
  3897.  
  3898. // Removing trade routes (if exists) for accurate rate
  3899. resources.Money.temp_rate = resources.Money.rate;
  3900. let totalTradeRoutes = null;
  3901. if (researched('tech-trade')) {
  3902. let totalTradeRouteStr = $('#tradeTotal').children()[0].innerText;
  3903. totalTradeRoutes = parseInt(/Trade Routes [\d]+ \/ ([\d]+)/.exec(totalTradeRouteStr)[1]);
  3904.  
  3905. // Clearing out trade routes
  3906. for (let x in resources) {
  3907. let resource = resources[x];
  3908. resource.temp_rate = resource.rate;
  3909. if (!(resource instanceof TradeableResource)) {continue;}
  3910. if (resource.tradeNum < 0) {
  3911. for (let i = 0;i < -resource.tradeNum;i++) {
  3912. resource.tradeInc();
  3913. resource.temp_rate += resource.tradeAmount;
  3914. resources.Money.temp_rate -= resource.tradeSellCost;
  3915. }
  3916. } else {
  3917. for (let i = 0;i < resource.tradeNum;i++) {
  3918. resource.tradeDec();
  3919. resource.temp_rate -= resource.tradeAmount;
  3920. resources.Money.temp_rate += resource.tradeBuyCost;
  3921. }
  3922. }
  3923. }
  3924. }
  3925.  
  3926. // Create priority queues for resources
  3927. let res = getAvailableResources();
  3928. let PQs = {}
  3929. let limits = {}
  3930. // Creating priority queues for each resource
  3931. for (let i = 0;i < res.length;i++) {
  3932. let curRes = res[i];
  3933. let pq = [];
  3934. // Checking each action for resource dependence
  3935. for (let j = 0;j < actions.length;j++) {
  3936. let cost = actions[j].getResDep(curRes.id);
  3937. //console.log(actions[j].id, cost);
  3938. if (cost !== null && cost > 0) {
  3939.  
  3940. pq.push(actions[j]);
  3941. // Setting up completion attribute
  3942. actions[j].completion[curRes.id.toLowerCase()] = false;
  3943. }
  3944. }
  3945. // Sorting actions by scaled priority
  3946. pq.sort(function(a,b) {
  3947. let aCost = priorityScale(a.res[curRes.id.toLowerCase()], a.priority, a);
  3948. let bCost = priorityScale(b.res[curRes.id.toLowerCase()], b.priority, b);
  3949. return aCost > bCost;
  3950. });
  3951.  
  3952. // Finding completion time and limiting resource
  3953. for (let j = 0;j < pq.length;j++) {
  3954. let action = pq[j];
  3955. // Already completed with current resources
  3956. // Scaling by 1.01 for rounding error
  3957. if (curRes.amount >= action.getResDep(curRes.id) * 1.01) {
  3958. action.completionTime[curRes.id] = 0;
  3959. } else {
  3960. let time = 0;
  3961. if (researched('tech-trade') && res instanceof TradeableResource) {
  3962. time = (action.getResDep(curRes.id) - curRes.amount) / curRes.temp_rate;
  3963. } else {
  3964. time = (action.getResDep(curRes.id) - curRes.amount) / curRes.rate;
  3965. }
  3966.  
  3967. time = (time < 0) ? 1 : time;
  3968. action.completionTime[curRes.id] = time;
  3969. //console.log(action.id, curRes.id, action.getResDep(curRes.id), curRes.amount, curRes.temp_rate, time);
  3970. if (time > action.maxCompletionTime) {
  3971. action.maxCompletionTime = time;
  3972. action.limitingRes = curRes.id;
  3973. }
  3974. }
  3975.  
  3976. }
  3977. PQs[curRes.id] = pq;
  3978. }
  3979.  
  3980. // Determining completion
  3981. for (let i = 0;i < res.length;i++) {
  3982. let curRes = res[i];
  3983. let pq = PQs[curRes.id];
  3984. limits[curRes.id] = null;
  3985. // Determining resource completion
  3986. // Resource filled, set all to completion
  3987. //console.log(curRes.id, curRes.ratio);
  3988. if (curRes.ratio > 0.99) {
  3989. //console.log(curRes.id, "ratio > 0.99. Set all to complete");
  3990. for (let j = 0;j < pq.length;j++) {
  3991. pq[j].completion[curRes.id.toLowerCase()] = true;
  3992. }
  3993. // Resource not full, allocate until reached action not filled.
  3994. } else {
  3995. let curAmount = curRes.amount;
  3996. //console.log(curRes.id, curAmount);
  3997. for (let j = 0;j < pq.length;j++) {
  3998. let action = pq[j];
  3999. //console.log(pq[j].id, pq[j].getResDep(curRes.id) , curAmount);
  4000. // Scaling by 1.01 for rounding error
  4001. if (action.getResDep(curRes.id) * 1.01 <= curAmount) {
  4002. // Action can be achieved with this resource
  4003. action.completion[curRes.id.toLowerCase()] = true;
  4004. // Determining how much of the resource to save for this action
  4005. if (action.limitingRes == curRes.id) {
  4006. // This resource is the limiting factor, give nothing to the next actions
  4007. curAmount -= action.getResDep(curRes.id);
  4008. action.keptRes[curRes.id] = action.getResDep(curRes.id);
  4009. } else {
  4010. // This resource isn't the limiting factor, give some leeway
  4011. // Higher priority, less leeway given
  4012. // Limiting resource will take a long time to complete, give more leeway
  4013. let priorityFactor = 1 / (1.0 + Math.exp(-0.1 * action.priority));
  4014. let timeFactor = Math.exp(-.005 * action.maxCompletionTime);
  4015. action.keptRes[curRes.id] = priorityFactor * timeFactor * action.getResDep(curRes.id)/2;
  4016. curAmount -= priorityFactor * timeFactor * action.getResDep(curRes.id);
  4017. }
  4018. } else {
  4019. // Action cannot be achieved with this resource
  4020. limits[curRes.id] = action;
  4021. break;
  4022. }
  4023. }
  4024. }
  4025.  
  4026. }
  4027.  
  4028. // Purchasing complete actions
  4029. actions.sort(prioCompare);
  4030. console.log("ACT:", actions);
  4031. for (let i = 0;i < actions.length;i++) {
  4032. let action = actions[i];
  4033. let canBuy = true;
  4034. for (let x in action.completion) {
  4035. if (!action.completion[x]) {
  4036. canBuy = false;
  4037. break;
  4038. }
  4039. }
  4040. if (canBuy) {
  4041. console.log(action.id, "can buy");
  4042. let clicked = action.click();
  4043. if (clicked) {
  4044. if (settings.autoPrint) {
  4045. messageQueue(getTotalGameDays().toString() + " [AUTO-PRIORITY] " + action.name, 'warning');
  4046. }
  4047. break;
  4048. }
  4049. }
  4050. }
  4051.  
  4052. if (settings.autoSmelter && (count % 20 == 0)) {
  4053. autoSmelter(limits);
  4054. }
  4055.  
  4056. // Determining rate priorities
  4057. console.log("LIM:", limits);
  4058. if (researched('tech-trade')) {
  4059. // Finding full resources
  4060. let sellingRes = [];
  4061. for (let x in resources) {
  4062. if (!resources[x].unlocked) {continue;}
  4063. if (!(resources[x] instanceof TradeableResource)) {continue;}
  4064. if (resources[x].ratio < 0.99) {continue;}
  4065. if (x == "Coal" || x == "Oil") {continue;}
  4066. sellingRes.push(resources[x]);
  4067. }
  4068. // Sort by sell cost
  4069. sellingRes.sort(function(a,b) {
  4070. return a.tradeSellCost < b.tradeSellCost;
  4071. });
  4072. // Finding sequence of selling trade routes
  4073. let sellSequence = [];
  4074. for (let i = 0;i < sellingRes.length;i++) {
  4075. let res = sellingRes[i];
  4076. let maxRoutes = Math.floor(res.temp_rate / res.tradeAmount);
  4077. let sellRoutes = (maxRoutes < totalTradeRoutes) ? maxRoutes : totalTradeRoutes;
  4078. for (let j = 0;j < sellRoutes;j++) {sellSequence.push(res.id);}
  4079. }
  4080. console.log("SELL SEQ:", sellSequence);
  4081.  
  4082. // Finding resource to focus on
  4083. let buyRes = null;
  4084. let focusList = [];
  4085. for (let x in limits) {
  4086. // There exists an action that requires this resource
  4087. if (limits[x] === null) {continue;}
  4088. // Excluding craftable resources
  4089. if (!(x in resources)) {continue;}
  4090. // Excluding knowledge
  4091. if (x == 'Knowledge') {continue;}
  4092. // Excluding actions whose resource is already filled
  4093. if (limits[x].completion[x] == true) {continue;}
  4094. if (buyRes === null) {
  4095. buyRes = x;
  4096. } else {
  4097. let curPriority = isFinite(limits[buyRes].completionTime[buyRes]) ? limits[buyRes].completionTime[buyRes] : 10000;
  4098. let nextPriority = isFinite(limits[x].completionTime[x]) ? limits[x].completionTime[x] : 10000;
  4099. curPriority = priorityScale(Math.log(curPriority), limits[buyRes].priority);
  4100. nextPriority = priorityScale(Math.log(nextPriority), limits[x].priority);
  4101. //if (limits[buyRes].priority <= limits[x].priority) {buyRes = x;}
  4102. if (curPriority > nextPriority) {buyRes = x;}
  4103. //if (limits[buyRes].completionTime[buyRes] < limits[x].completionTime[x]) {buyRes = x;}
  4104. }
  4105. focusList.push({action:limits[x], res:x});
  4106. //console.log(x, limits[x].id, limits[x].completionTime, priorityScale(Math.log(limits[x].completionTime[x]), limits[x].priority), limits[x].priority);
  4107. }
  4108. if (buyRes !== null) {console.log("Focusing on", buyRes, "for", limits[buyRes].name);}
  4109. if (focusList.length > 0) {
  4110. focusList.sort(function(a,b) {
  4111. return prioCompare(a.action, b.action);
  4112. });
  4113. }
  4114. let prioMultiplier = {
  4115. Money:2,
  4116. Food:0,
  4117. Lumber:0,
  4118. Stone:0,
  4119. Furs:.5,
  4120. Copper:.75,
  4121. Iron:.75,
  4122. Aluminium:.5,
  4123. Cement:.75,
  4124. Coal:0,
  4125. Oil:3,
  4126. Uranium:3,
  4127. Steel:2,
  4128. Titanium:5,
  4129. Alloy:5
  4130. };
  4131. console.log("FOC LIST:", focusList);
  4132. let focusSequence = [];
  4133. let curNum = {};
  4134. let curRatio = {};
  4135. let wantedRatio = {};
  4136. let totalPriority = 0;
  4137. if (focusList.length > 0) {
  4138. // Creating sequence of trade route allocations to match priority ratios
  4139. let curError = 0;
  4140. for (let i = 0;i < focusList.length;i++) {totalPriority += focusList[i].action.priority;}
  4141. for (let i = 0;i < focusList.length;i++) {
  4142. curNum[focusList[i].res] = 0;
  4143. wantedRatio[focusList[i].res] = prioMultiplier[focusList[i].res] * focusList[i].action.priority / totalPriority;
  4144. }
  4145. for (let i = 0;i < totalTradeRoutes;i++) {
  4146. // Calculating error based on next value choice
  4147. let error = -1;
  4148. let choice = -1;
  4149. for (let j = 0;j < focusList.length;j++) {
  4150. let total = i+1;
  4151. let tempError = 0;
  4152. // Finding new error based on adding this trade route
  4153. for (let k = 0;k < focusList.length;k++) {
  4154. if (j == k) {
  4155. // Currently attempting to add a trade route to this resource
  4156. tempError += (((curNum[focusList[k].res]+1) / total) - wantedRatio[focusList[k].res]) ** 2;
  4157. } else {
  4158. tempError += ((curNum[focusList[k].res] / total) - wantedRatio[focusList[k].res]) ** 2;
  4159. }
  4160. }
  4161. if (error == -1 || tempError < error) {
  4162. error = tempError;
  4163. choice = j;
  4164. }
  4165. }
  4166. focusSequence[i] = focusList[choice].res;
  4167. curNum[focusList[choice].res] += 1;
  4168. }
  4169. console.log("FOC SEQ:", focusSequence);
  4170. } else {
  4171. for (let i = 0;i < totalTradeRoutes;i++) {
  4172. focusSequence.push('Money');
  4173. }
  4174. }
  4175.  
  4176. // Allocating trade routes
  4177. let curFocus = 0;
  4178. let curSell = 0;
  4179. if (focusList.length > 0) {
  4180. // Allocating all possible trade routes with given money
  4181. let curFreeTradeRoutes = totalTradeRoutes;
  4182. // Keeping fraction of base money for money
  4183. if (wantedRatio.Money > 0) {resources.Money.temp_rate *= wantedRatio.Money;}
  4184. while (resources.Money.temp_rate > 0 && curFreeTradeRoutes > 0) {
  4185. //console.log("CUR", curFocus, focusSequence[curFocus]);
  4186. if (focusSequence[curFocus] == 'Money') {
  4187. //console.log("Focusing on Money");
  4188. // Focusing on money, add a sell trade route
  4189. if (curSell == sellSequence.length) {curFocus+=1;continue;}
  4190. resources[sellSequence[curSell]].tradeDec();
  4191. curFreeTradeRoutes -= 1;
  4192. curSell += 1;
  4193. curFocus += 1;
  4194. } else {
  4195. // Focusing on resource
  4196. //console.log("Focusing on", focusSequence[curFocus]);
  4197. if (resources.Money.temp_rate > resources[focusSequence[curFocus]].tradeBuyCost) {
  4198. //console.log("Buying", focusSequence[curFocus], curFocus);
  4199. resources[focusSequence[curFocus]].tradeInc();
  4200. resources.Money.temp_rate -= resources[focusSequence[curFocus]].tradeBuyCost;
  4201. curFreeTradeRoutes -= 1;
  4202. curFocus += 1;
  4203. } else {
  4204. break;
  4205. }
  4206. }
  4207. }
  4208.  
  4209. // Begin allocating algorithm
  4210. while (curFreeTradeRoutes > 0) {
  4211. // Checking if can buy trade route
  4212. if (focusSequence[curFocus] == 'Money') {curFocus += 1; continue;}
  4213. if (resources.Money.temp_rate > resources[focusSequence[curFocus]].tradeBuyCost) {
  4214. // Can buy trade route
  4215. //console.log("Buying", focusSequence[curFocus], curFocus);
  4216. resources[focusSequence[curFocus]].tradeInc();
  4217. resources.Money.temp_rate -= resources[focusSequence[curFocus]].tradeBuyCost;
  4218. curFreeTradeRoutes -= 1;
  4219. curFocus += 1;
  4220. } else {
  4221. // Cannot buy trade route, sell instead
  4222. if (curSell == sellSequence.length) {break;}
  4223. resources[sellSequence[curSell]].tradeDec();
  4224. resources.Money.temp_rate += resources[sellSequence[curSell]].tradeSellCost;
  4225. curFreeTradeRoutes -= 1;
  4226. curSell += 1;
  4227. }
  4228. }
  4229. }
  4230. /*
  4231.  
  4232. // Checking if can fully allocate towards limiting resource
  4233. if (buyRes !== null && buyRes !== undefined && buyRes != "Money") {
  4234. // Limiting resource is not money
  4235. // Allocate as much as you can already
  4236. let curFreeTradeRoutes = totalTradeRoutes;
  4237. let maxBuyRoutes = Math.floor(resources.Money.temp_rate / resources[buyRes].tradeBuyCost);
  4238. while (resources.Money.temp_rate > 0 && curFreeTradeRoutes > 0) {
  4239. if (resources.Money.temp_rate > resources[buyRes].tradeBuyCost) {
  4240. resources[buyRes].tradeInc();
  4241. resources.Money.temp_rate -= resources[buyRes].tradeBuyCost;
  4242. curFreeTradeRoutes -= 1;
  4243. } else {
  4244. break;
  4245. }
  4246. }
  4247. // Begin allocating selling routes
  4248. for (let i = 0;i < sellingRes.length;i++) {
  4249. let res = sellingRes[i];
  4250. let maxRoutes = Math.floor(res.temp_rate / res.tradeAmount);
  4251. let sellRoutes = (maxRoutes < curFreeTradeRoutes) ? maxRoutes : curFreeTradeRoutes;
  4252. for (let j = 0;j < sellRoutes;j++) {
  4253. res.tradeDec();
  4254. resources.Money.temp_rate += res.tradeSellCost;
  4255. curFreeTradeRoutes -= 1;
  4256. if (curFreeTradeRoutes == 0) {break;}
  4257. if (resources.Money.temp_rate > resources[buyRes].tradeBuyCost) {
  4258. resources[buyRes].tradeInc();
  4259. resources.Money.temp_rate -= resources[buyRes].tradeBuyCost;
  4260. curFreeTradeRoutes -= 1;
  4261. if (curFreeTradeRoutes == 0) {break;}
  4262. }
  4263. }
  4264. }
  4265. } else {
  4266. // Limiting resource is money, or doesn't exist. Focus on money
  4267. let curFreeTradeRoutes = totalTradeRoutes;
  4268. for (let i = 0;i < sellingRes.length;i++) {
  4269. let res = sellingRes[i];
  4270. let maxRoutes = Math.floor(res.temp_rate / res.tradeAmount);
  4271. if (maxRoutes < curFreeTradeRoutes) {
  4272. for (let j = 0;j < maxRoutes;j++) {
  4273. res.tradeDec();
  4274. }
  4275. curFreeTradeRoutes -= maxRoutes;
  4276. } else {
  4277. for (let j = 0;j < curFreeTradeRoutes;j++) {
  4278. res.tradeDec();
  4279. }
  4280. break;
  4281. }
  4282. }
  4283. } */
  4284. }
  4285.  
  4286. console.log("PQ:", PQs);
  4287. }
  4288.  
  4289. function autoTrade(limits) {
  4290. //console.log("Beginning auto trade");
  4291.  
  4292. let curMoneyRate = resources.Money.rate;
  4293. let totalTradeRouteStr = $('#tradeTotal').children()[0].innerText;
  4294. let totalTradeRoutes = parseInt(/Trade Routes [\d]+ \/ ([\d]+)/.exec(totalTradeRouteStr)[1]);
  4295. let x;
  4296. // Clearing out trade routes
  4297. for (x in resources) {
  4298. let resource = resources[x];
  4299. if (!(resource instanceof TradeableResource)) {continue;}
  4300. resource.temp_rate = resource.rate;
  4301. if (resource.tradeNum < 0) {
  4302. for (let i = 0;i < -resource.tradeNum;i++) {
  4303. resource.tradeInc();
  4304. resource.temp_rate += resource.tradeAmount;
  4305. curMoneyRate -= resource.tradeSellCost;
  4306. }
  4307. } else {
  4308. for (let i = 0;i < resource.tradeNum;i++) {
  4309. resource.tradeDec();
  4310. resource.temp_rate -= resource.tradeAmount;
  4311. curMoneyRate += resource.tradeBuyCost;
  4312. }
  4313. }
  4314. }
  4315.  
  4316. // Finding full resources
  4317. let sellingRes = [];
  4318. for (x in resources) {
  4319. if (!resources[x].unlocked) {continue;}
  4320. if (!(resources[x] instanceof TradeableResource)) {continue;}
  4321. if (resources[x].ratio < 0.99) {continue;}
  4322. if (x == "Coal" || x == "Oil") {continue;}
  4323. sellingRes.push(resources[x]);
  4324. }
  4325. // Finding resource to focus on
  4326. let buyRes = null;
  4327. for (x in limits) {
  4328. // There exists an action that requires this resource
  4329. if (limits[x] === null) {continue;}
  4330. // Excluding craftable resources
  4331. if (!(x in resources)) {continue;}
  4332. // Excluding knowledge
  4333. if (x == 'Knowledge') {continue;}
  4334. // Excluding actions whose resource is already filled
  4335. if (limits[x].completionTime[x] == 0) {continue;}
  4336. if (buyRes === null) {
  4337. buyRes = x;
  4338. } else {
  4339. let curPriority = isFinite(limits[buyRes].completionTime[buyRes]) ? limits[buyRes].completionTime[buyRes] : 10000;
  4340. let nextPriority = isFinite(limits[x].completionTime[x]) ? limits[x].completionTime[x] : 10000;
  4341. curPriority = priorityScale(Math.log(curPriority), limits[buyRes].priority);
  4342. nextPriority = priorityScale(Math.log(nextPriority), limits[x].priority);
  4343. //if (limits[buyRes].priority <= limits[x].priority) {buyRes = x;}
  4344. if (curPriority > nextPriority) {buyRes = x;}
  4345. }
  4346. console.log(x, limits[x].id, limits[x].completionTime, priorityScale(Math.log(limits[x].completionTime[x]), limits[x].priority), limits[x].priority);
  4347. }
  4348. if (buyRes !== null) {console.log("Focusing on", buyRes, "for", limits[buyRes].name);}
  4349.  
  4350. // Sort by sell cost
  4351. sellingRes.sort(function(a,b) {
  4352. return a.tradeSellCost < b.tradeSellCost;
  4353. });
  4354.  
  4355. // Allocating trade routes
  4356. // Checking if can fully allocate towards limiting resource
  4357. if (buyRes !== null && buyRes !== undefined && buyRes != "Money") {
  4358. // Limiting resource is not money
  4359. // Allocate as much as you can already
  4360. let curFreeTradeRoutes = totalTradeRoutes;
  4361. let maxBuyRoutes = Math.floor(curMoneyRate / resources[buyRes].tradeBuyCost);
  4362. for (let j = 0;j < Math.min(maxBuyRoutes, totalTradeRoutes);j++) {
  4363. resources[buyRes].tradeInc();
  4364. curMoneyRate -= resources[buyRes].tradeBuyCost;
  4365. curFreeTradeRoutes -= 1;
  4366. }
  4367. // Begin allocating selling routes
  4368. for (let i = 0;i < sellingRes.length;i++) {
  4369. let res = sellingRes[i];
  4370. let maxRoutes = Math.floor(res.temp_rate / res.tradeAmount);
  4371. let sellRoutes = (maxRoutes < curFreeTradeRoutes) ? maxRoutes : curFreeTradeRoutes;
  4372. for (let j = 0;j < sellRoutes;j++) {
  4373. res.tradeDec();
  4374. curMoneyRate += res.tradeSellCost;
  4375. curFreeTradeRoutes -= 1;
  4376. if (curFreeTradeRoutes == 0) {break;}
  4377. if (curMoneyRate > resources[buyRes].tradeBuyCost) {
  4378. resources[buyRes].tradeInc();
  4379. curMoneyRate -= resources[buyRes].tradeBuyCost;
  4380. curFreeTradeRoutes -= 1;
  4381. if (curFreeTradeRoutes == 0) {break;}
  4382. }
  4383. }
  4384. }
  4385. } else {
  4386. // Limiting resource is money, or doesn't exist. Focus on money
  4387. let curFreeTradeRoutes = totalTradeRoutes;
  4388. for (let i = 0;i < sellingRes.length;i++) {
  4389. let res = sellingRes[i];
  4390. let maxRoutes = Math.floor(res.temp_rate / res.tradeAmount);
  4391. if (maxRoutes < curFreeTradeRoutes) {
  4392. for (let j = 0;j < maxRoutes;j++) {
  4393. res.tradeDec();
  4394. }
  4395. curFreeTradeRoutes -= maxRoutes;
  4396. } else {
  4397. for (let j = 0;j < curFreeTradeRoutes;j++) {
  4398. res.tradeDec();
  4399. }
  4400. break;
  4401. }
  4402. }
  4403. }
  4404. }
  4405.  
  4406. function autoArpa(){
  4407. // If haven't unlocked ARPA, don't autoArpa
  4408. if (!researched('tech-arpa')) {return;}
  4409. if(settings.arpa.lhc){
  4410. let btn = document.querySelector("#arpalhc > div.buy > button.button.x1");
  4411. if(btn != null && !wouldBreakMoneyFloor(26500)){
  4412. btn.click();
  4413. }
  4414. }
  4415. if(settings.arpa.stock_exchange){
  4416. let btn = document.querySelector("#arpastock_exchange > div.buy > button.button.x1");
  4417. if(btn != null && !wouldBreakMoneyFloor(30000)){
  4418. btn.click();
  4419. }
  4420. }
  4421. if(settings.arpa.monument){
  4422. let btn = document.querySelector("#arpamonument > div.buy > button.button.x1");
  4423. if(btn != null){
  4424. btn.click();
  4425. }
  4426. }
  4427. if(settings.arpa.launch_facility){
  4428. let btn = document.querySelector("#arpalaunch_facility > div.buy > button.button.x1");
  4429. if(btn != null && !wouldBreakMoneyFloor(20000)){
  4430. btn.click();
  4431. }
  4432. }
  4433. // speed up gene creation
  4434. if(resources.Knowledge.amount == resources.Knowledge.storage){
  4435. let btn = document.querySelectorAll('#arpaGenetics button')[2];
  4436. if(btn) {
  4437. let count = parseInt(resources.Knowledge.amount / 200000);
  4438. while(count--){
  4439. btn.click();
  4440. }
  4441. }
  4442. }
  4443. }
  4444. function autoReset(){
  4445. if (!researched('tech-mad')) {return;}
  4446. const buttons = $('#mad button');
  4447. if(buttons.length != 2){
  4448. console.error('Wrong reset buttons', buttons);
  4449. return;
  4450. }
  4451. const arm = buttons[0];
  4452. const launch = buttons[1];
  4453. if(arm.innerText.indexOf('Arm') == 0){
  4454. arm.click();
  4455. return; // skip a cycle for chance to stop
  4456. }
  4457. launch.click();
  4458. }
  4459.  
  4460. let count = 0;
  4461. function fastAutomate() {
  4462. //console.clear();
  4463. //console.log(count);
  4464. updateUI();
  4465. loadSettings();
  4466. updateSettings();
  4467. autoFarm();
  4468. let noKeys = !ctrlDown && !altDown && !shiftDown;
  4469. if ($('#mainColumn > .content > .b-tabs > .tabs > ul > li:nth-child(1)')[0].style.display != 'none') {
  4470. // Evolution Automation
  4471. if(settings.autoEvolution) {
  4472. autoEvolution();
  4473. }
  4474. } else {
  4475. // Civilization Automation
  4476. if(settings.autoCraft && noKeys){
  4477. autoCraft();
  4478. }
  4479. if(settings.autoBuild && !settings.autoPrioritize){
  4480. autoBuild();
  4481. }
  4482. if(settings.autoSupport && noKeys) {
  4483. autoSupport();
  4484. }
  4485. if(settings.autoEmploy && noKeys){
  4486. autoEmployer.autoEmploy();
  4487. }
  4488. if(settings.autoTax && noKeys) {
  4489. autoTax();
  4490. }
  4491. if(settings.autoBattle){
  4492. autoBattler.autoBattle();
  4493. }
  4494. if(settings.autoResearch && !settings.autoPrioritize){
  4495. autoResearch();
  4496. }
  4497. if(settings.autoMarket && noKeys){
  4498. autoMarket();
  4499. }
  4500. if(settings.autoARPA && !settings.autoPrioritize){
  4501. autoArpa();
  4502. }
  4503. if(settings.autoPrioritize) {
  4504. autoPrioritize(count);
  4505. }
  4506. }
  4507. count += 1;
  4508. }
  4509. setInterval(fastAutomate, 1000);
  4510.  
  4511. function midAutomate() {
  4512. let noKeys = !ctrlDown && !altDown && !shiftDown;
  4513. if ($('#resStorage')[0] && settings.autoStorage) {
  4514. autoStorage();
  4515. }
  4516. if(settings.autoReset && noKeys){
  4517. autoReset();
  4518. }
  4519. if (settings.autoSmelter && noKeys) {
  4520. autoSmelter();
  4521. }
  4522. if (settings.autoFactory && noKeys) {
  4523. autoFactory();
  4524. }
  4525. }
  4526. setInterval(midAutomate, 100000);
  4527.  
  4528. //Temporary
  4529. let stardockBtn = $('#space-star_dock > .special');
  4530. function temp() {
  4531. stardockBtn.click();
  4532. setTimeout(function() {
  4533. let seederBtn = $('#spcdock-seeder > .button')[0];
  4534. let probeBtn = $('#spcdock-probes > .button')[0];
  4535. seederBtn.click();
  4536. probeBtn.click();
  4537. setTimeout(function() {
  4538. let exitBtn = $('.modal > .modal-close').click();
  4539. }, 1000);
  4540.  
  4541. }, 1000);
  4542. }
  4543. //setInterval(temp, 4000);
  4544. function temp2() {
  4545. if (resources.Knowledge.amount > 200000) {
  4546. $('#arpaSequence > span > button')[1].click();
  4547. }
  4548. //resetUI();
  4549. }
  4550. //setInterval(temp2, 20000);
  4551.  
  4552. // Refreshing page every 20min to update data-values in elements
  4553. //HOW ABOUT not reloading the page for someone who plays ocasionally in a train with no wifi.
  4554. //setInterval(function() {
  4555. //location.reload();
  4556. //}, 20 * 60 * 1000)
  4557.  
  4558. // import vars.js
  4559. var body = unsafeWindow.document.body;
  4560. var script = unsafeWindow.document.createElement('script');
  4561. script.type = 'module';
  4562. const stuff = "import('./vars.js').then((module) => {window.vars = module;});" +
  4563. "import('./main.js').then((module) => {window.main = module;});"
  4564. script.innerHTML = stuff;
  4565. body.appendChild(script);
  4566.  
  4567. //worker
  4568. var worker = new unsafeWindow.Worker('evolve.js');
  4569.  
  4570. /***
  4571. *
  4572. * Setup UI
  4573. *
  4574. ***/
  4575.  
  4576. function createSettingToggle(name, title, enabledCallBack, disabledCallBack){
  4577. let parent = $('#resources');
  4578. let toggle = $('<label tabindex="0" class="switch" id="'+name+'_toggle" style="" title="'+title+'"><input type="checkbox" value=false> <span class="check"></span><span>'+name+'</span></label>');
  4579. let divLeft = $('<div id="'+name+'_left" style="float:left">').append(toggle).append($('</div>'));
  4580. let divRight = $('<div id="'+name+'_right" style="float:right"></div>');
  4581. let mainDiv = $('<div id="'+name+'" style="overflow:auto">').append(divLeft).append(divRight).append($('</div>'));
  4582. parent.append(mainDiv);
  4583. if(settings[name]){
  4584. toggle.click();
  4585. toggle.children('input').attr('value', true);
  4586. if(enabledCallBack !== undefined){
  4587. enabledCallBack();
  4588. }
  4589. }
  4590. toggle.on('mouseup', function(e){
  4591. if (e.which != 1) {return;}
  4592. let input = e.currentTarget.children[0];
  4593. let state = !(input.getAttribute('value') === "true");
  4594. input.setAttribute('value', state);
  4595. settings[name] = state;
  4596. console.log("Setting", name, "to", state);
  4597. updateSettings();
  4598. if(state && enabledCallBack !== undefined){
  4599. enabledCallBack();
  4600. } else if(disabledCallBack !== undefined){
  4601. disabledCallBack()
  4602. }
  4603. });
  4604. }
  4605.  
  4606. function updateUI(){
  4607. if ($('#autoPrint').length == 0) {
  4608. createSettingToggle('autoPrint', 'Turns on print statements for autoscript messages');
  4609. }
  4610. if ($('.ea-autolog').length == 0) {
  4611. createAutoLog();
  4612. }
  4613. if ($('#reload').length == 0) {
  4614. let reloadBtn = $('<a class="button is-dark is-small" id="reload" title="Resets UI and internal data"><span>Reload</span></a>');
  4615. reloadBtn.on('mouseup', function(e){
  4616. if (e.which != 1) {return;}
  4617. resetUI();
  4618. updateSettings();
  4619. loadSettings();
  4620. });
  4621. $('#autoPrint_right').append(reloadBtn);
  4622. }
  4623. if ($('#autoFarm').length == 0){
  4624. createSettingToggle('autoFarm', 'Turns on autofarming of resources');
  4625. }
  4626. // If not currently in the evolution stage (thus civilization stage
  4627. if($('#mainColumn > .content > .b-tabs > .tabs > ul > li:nth-child(1)')[0].style.display == 'none') {
  4628. // These toggles only appear after the evolution stage is over
  4629. // Creating Buildings Tab
  4630. if ($('.ea-buildings-tab').length == 0) {
  4631. createBuildingsTab();
  4632. }
  4633. // Create Research Tab
  4634. if ($('.ea-research-tab').length == 0) {
  4635. createResearchTab();
  4636. }
  4637. // Crafting requires foundries
  4638. if ($('#autoStorage').length == 0 && researched('tech-containerization')) {
  4639. createSettingToggle('autoStorage', 'Automatically assigns crates and containers to resources', createStorageSettings, removeStorageSettings);
  4640. } else if (settings.autoStorage && $('.ea-storage-settings').length == 0 && researched('tech-containerization')) {
  4641. createStorageSettings();
  4642. }
  4643. if ($('#autoCraft').length == 0 && researched('tech-foundry')) {
  4644. createSettingToggle('autoCraft', 'Automatically crafts craftable resources when resource ratio is above 0.9', createCraftSettings, removeCraftSettings);
  4645. } else if (settings.autoCraft && $('.ea-craft-settings').length == 0 && researched('tech-foundry')) {
  4646. createCraftSettings();
  4647. }
  4648. if ($('#autoBuild').length == 0) {
  4649. createSettingToggle('autoBuild', 'Automatically builds buildings when available. Can disable specific buildings with unique toggles', createBuildingSettings, removeBuildingSettings);
  4650. } else if (settings.autoBuild && $('.ea-building-settings').length == 0) {
  4651. createBuildingSettings();
  4652. }
  4653. if ($('#autoSmelter').length == 0 && researched('tech-smelting')) {
  4654. createSettingToggle('autoSmelter', 'Automatically allocates resources in the smelter. See Buildings tab for more settings', createSmelterSettings, removeSmelterSettings);
  4655. } else if (settings.autoSmelter && $('.ea-smelter-settings').length == 0 && researched('tech-smelting')) {
  4656. createSmelterSettings();
  4657. }
  4658. if ($('#autoFactory').length == 0 && researched('tech-industrialization')) {
  4659. createSettingToggle('autoFactory', 'Automatically allocates resources in the factory. See Buildings tab for more settings', createFactorySettings, removeFactorySettings);
  4660. } else if (settings.autoFactory && $('.ea-factory-settings').length == 0 && researched('tech-factory')) {
  4661. createFactorySettings();
  4662. }
  4663. // Support requires electricity
  4664. if ($('#autoSupport').length == 0 && researched("tech-electricity")) {
  4665. createSettingToggle('autoSupport', 'Automatically powers buildings and supports space buildings. See the Support Tab for more settings', createSupportSettings, removeSupportSettings);
  4666. } else if (settings.autoSupport && $('.ea-support-settings').length == 0 && researched("tech-electricity")) {
  4667. createSupportSettings();
  4668. }
  4669. if ($('#autoEmploy').length == 0) {
  4670. createSettingToggle('autoEmploy', 'Autoemploys workers. See Civics page for job priorities', createEmploySettings, removeEmploySettings);
  4671. } else if(settings.autoEmploy && ($('.ea-employ-settings').length == 0 || $('.ea-employ-craft-settings').length == 0)) {
  4672. createEmploySettings();
  4673. }
  4674. // Tax requires tax rates researched
  4675. if ($('#autoTax').length == 0 && researched('tech-tax_rates')) {
  4676. createSettingToggle('autoTax', 'Automatically changes tax rate to match desired morale level', createTaxSettings, removeTaxSettings);
  4677. }
  4678. // Battles require garrisions
  4679. if (
  4680. $('#autoBattle').length == 0 &&
  4681. (
  4682. researched('tech-garrison') && !(researched('tech-wc_conquest')||researched('tech-wc_morale')||researched('tech-wc_money')||researched('tech-wc_reject')) ||
  4683. researched('tech-fort')
  4684. )
  4685. ) {
  4686. createSettingToggle('autoBattle', 'Automatically battles when all soldiers are ready. Changes the campaign type to match army rating');
  4687. }
  4688. if ($('#autoResearch').length == 0) {
  4689. createSettingToggle('autoResearch', 'Automatically researches. See Research > Auto Settings tab for more settings');
  4690. }
  4691. // Markets require market researched
  4692. if ($('#autoMarket').length == 0 && researched('tech-market')) {
  4693. createSettingToggle('autoMarket', 'Auto buys/sells resources at certain ratios. See Market tab for more settings', createMarketSettings, removeMarketSettings);
  4694. } else if (settings.autoMarket > 0 && $('.ea-market-settings').length == 0 && researched('tech-market')) {
  4695. createMarketSettings()
  4696. }
  4697. if ($('#ea-settings').length == 0) {
  4698. let settingsDiv = $('<div id="ea-settings" style="overflow:auto;" title="Sets the minimum amount of money to keep. Can input real money value or ratio"></div>');
  4699. let minMoneyTxt = $('<div style="float:left;">Minimum money to keep :</div>')
  4700. let minMoneyInput = $('<input type="text" class="input is-small" style="width:20%;float:right;"/>');
  4701. minMoneyInput.val(settings.minimumMoney);
  4702. let setBtn = $('<a class="button is-dark is-small" id="set-min-money" style="float:right;"><span>set</span></a>');
  4703. settingsDiv.append(minMoneyTxt).append(setBtn).append(minMoneyInput);
  4704. $('#resources').append(settingsDiv);
  4705.  
  4706. setBtn.on('mouseup', function(e) {
  4707. if (e.which != 1) {return;}
  4708. let val = minMoneyInput.val();
  4709. let minMoney = getRealValue(val);
  4710. if(!isNaN(minMoney)){
  4711. console.log("Setting minimum Money", minMoney);
  4712. settings.minimumMoney = minMoney;
  4713. updateSettings();
  4714. }
  4715. });
  4716. }
  4717. if ($('#autoARPA').length == 0 && researched('tech-arpa')){
  4718. createSettingToggle('autoARPA', 'Automatically funds A.R.P.A. research projects. See the A.R.P.A. tab for more settings', createArpaToggles, removeArpaToggles);
  4719. }else if(settings.autoArpa && $('.ea-arpa-toggle').length == 0) {
  4720. createArpaToggles();
  4721. }
  4722. if ($('#autoPrioritize').length == 0) {
  4723. createSettingToggle('autoPrioritize', 'Complex priority system to control purchasing buildings and research');
  4724. }
  4725. if ($('#autoReset').length == 0) {
  4726. createSettingToggle('autoReset', 'When Mutually Assured Destruction is researched, use it.');
  4727. }
  4728. }else{
  4729. // Currently in the evolution stage, reset civilization settings
  4730. if ($('#autoEvolution').length == 0) {
  4731. createSettingToggle("autoEvolution", "Automatically plays the evolution stage", createEvolutionSettings, removeEvolutionSettings);
  4732. } else if (settings.autoEvolution && $('.ea-evolution-settings').length == 0) {
  4733. createEvolutionSettings();
  4734. }
  4735. }
  4736. if ($('#autoSettings').length == 0) {
  4737. createAutoSettings();
  4738. }
  4739. }
  4740.  
  4741. function resetUI() {
  4742. console.log("Resetting UI");
  4743. ctrlDown = false;
  4744. altDown = false;
  4745. shiftDown = false;
  4746. removeEvolutionSettings();
  4747. removeStorageSettings();
  4748. removeCraftSettings();
  4749. removeBuildingSettings();
  4750. removeSmelterSettings();
  4751. removeFactorySettings();
  4752. removeSupportSettings();
  4753. removeMarketSettings();
  4754. removeEmploySettings();
  4755. removeTaxSettings();
  4756. removeArpaToggles();
  4757. $('.ea-buildings-tab').remove();
  4758. $('.ea-research-tab').remove();
  4759. $('.ea-autolog').remove();
  4760. $('#reload').remove();
  4761. $('#autoPrint').remove();
  4762. $('#autoFarm').remove();
  4763. $('#autoEvolution').remove();
  4764. $('#autoStorage').remove();
  4765. $('#autoCraft').remove();
  4766. $('#autoBuild').remove();
  4767. $('#autoSmelter').remove();
  4768. $('#autoFactory').remove();
  4769. $('#autoSupport').remove();
  4770. $('#autoPrioritize').remove();
  4771. $('#autoEmploy').remove();
  4772. $('#autoTax').remove();
  4773. $('#autoBattle').remove();
  4774. $('#autoResearch').remove();
  4775. $('#autoMarket').remove();
  4776. $('#ea-settings').remove();
  4777. $('#autoARPA').remove();
  4778. $('#autoReset').remove();
  4779. $('#autoSettings').remove();
  4780. }
  4781.  
  4782. function createAutoSettings() {
  4783. let parent = $('#settings');
  4784. parent.append($('<br></br>'));
  4785. let mainDiv = $('<div id="autoSettings"></div>');
  4786. let label = $('<label class="label">Import/Export Auto Settings</label>');
  4787. let ctrlDiv = $('<div class="control is-clearfix"></div>');
  4788. let textArea = $('<textarea id="settingsImportExport" class="textarea"></textarea>');
  4789. ctrlDiv.append(textArea);
  4790. let control = $('<div class="field"></div>');
  4791. control.append(label).append(ctrlDiv);
  4792. let importBtn = $('<button class="button">Import Settings</button><text> </text>');
  4793. importBtn.on('mouseup', function(e) {
  4794. if (e.which != 1) {return;}
  4795. importSettings();
  4796. });
  4797. let exportBtn = $('<button class="button">Export Settings</button>');
  4798. exportBtn.on('mouseup', function(e) {
  4799. if (e.which != 1) {return;}
  4800. exportSettings();
  4801. });
  4802. mainDiv.append(control).append(importBtn).append(exportBtn);
  4803. parent.append(mainDiv);
  4804. }
  4805.  
  4806. function createEvolutionToggle(name) {
  4807. let parent = $('#resources');
  4808. let toggle = $('<label tabindex="0" class="switch" id="'+name+'_toggle" style=""><input type="checkbox" value=false> <span class="check"></span><span>'+name+'</span></label>');
  4809. let box = $('<div id="'+name+'" class="ea-evolution-settings" style="padding-left:20px;"></div>');
  4810. box.append(toggle);
  4811. parent.append(box);
  4812. if(settings[name]){
  4813. toggle.click();
  4814. toggle.children('input').attr('value', true);
  4815. }
  4816. toggle.on('mouseup', function(e){
  4817. if (e.which != 1) {return;}
  4818. let input = e.currentTarget.children[0];
  4819. let state = !(input.getAttribute('value') === "true");
  4820. input.setAttribute('value', state);
  4821. settings[name] = state;
  4822. updateSettings();
  4823. });
  4824. }
  4825. function createEvolutionSettings() {
  4826. removeEvolutionSettings();
  4827. let evoDecision = $(`<select class="ea-evolution-settings" style="width:150px;">
  4828. <option value="elven">Elven</option>
  4829. <option value="orc">Orc</option>
  4830. <option value="human">Human</option>
  4831. <option value="troll">Troll</option>
  4832. <option value="orge">Ogre</option>
  4833. <option value="cylops">Cyclops</option>
  4834. <option value="kobold">Kobold</option>
  4835. <option value="goblin">Goblin</option>
  4836. <option value="gnome">Gnome</option>
  4837. <option value="cath">Cath</option>
  4838. <option value="wolven">Wolven</option>
  4839. <option value="centuar">Centuar</option>
  4840. <option value="tortoisan">Tortoisan</option>
  4841. <option value="gecko">Gecko</option>
  4842. <option value="slitheryn">Slitheryn</option>
  4843. <option value="arraak">Arraak</option>
  4844. <option value="pterodacti">Pterodacti</option>
  4845. <option value="dracnid">Dracnid</option>
  4846. <option value="sporgar">Sporgar</option>
  4847. <option value="shroomi">Shroomi</option>
  4848. <option value="mantis">Mantis</option>
  4849. <option value="scorpid">Scorpid</option>
  4850. <option value="antid">Antid</option>
  4851. <option value="entish">Entish</option>
  4852. <option value="cacti">Cacti</option>
  4853. <option value="sharkin">Sharkin</option>
  4854. <option value="octigoran">Octigoran</option>
  4855. <option value="balorg">Balorg</option>
  4856. <option value="imp">Imp</option>
  4857. </select>`);
  4858. evoDecision[0].value = settings.evolution;
  4859. evoDecision[0].onchange = function(){
  4860. settings.evolution = evoDecision[0].value;
  4861. console.log("Changing target to ", settings.evolution);
  4862. updateSettings();
  4863. };
  4864. $('#autoEvolution_right').append(evoDecision);
  4865. createEvolutionToggle('Plasmid');
  4866. createEvolutionToggle('Craft');
  4867. createEvolutionToggle('CRISPR');
  4868. createEvolutionToggle('Trade');
  4869. createEvolutionToggle('Junker');
  4870. createEvolutionToggle('Joyless');
  4871. createEvolutionToggle('Decay');
  4872.  
  4873. }
  4874. function removeEvolutionSettings() {
  4875. $('.ea-evolution-settings').remove();
  4876. }
  4877.  
  4878. function createStorageSetting(id) {
  4879. if (!resources[id].unlocked) {return;}
  4880. if (!resources[id].crateable) {return;}
  4881. let resourceSpan = $('#res'+resources[id].id);
  4882. let prioritySub = $('<span role="button" aria-label="Decrease '+resources[id].name+' Priority" class="sub ea-storage-settings" style="width:25%">«</span>');
  4883. prioritySub.on('mouseup', function(e) {
  4884. if (e.which != 1) {return;}
  4885. resources[id].decStorePriority();
  4886. priorityLabel[0].removeChild(priorityLabel[0].firstChild);
  4887. priorityLabel[0].appendChild(document.createTextNode(resources[id].storePriority));
  4888. });
  4889. let priorityAdd = $('<span role="button" aria-label="Increase '+resources[id].name+' Priority" class="add ea-storage-settings" style="width:25%">»</span>');
  4890. priorityAdd.on('mouseup', function(e) {
  4891. if (e.which != 1) {return;}
  4892. resources[id].incStorePriority();
  4893. priorityLabel[0].removeChild(priorityLabel[0].firstChild);
  4894. priorityLabel[0].appendChild(document.createTextNode(resources[id].storePriority));
  4895. });
  4896. let priorityLabel = $('<span class="count current" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:30%;text-align:center;">'+resources[id].storePriority+'</span>');
  4897. let priorityControls = $('<div class="controls ea-storage-settings" style="position:absolute;left:5.5%;">').append(prioritySub).append(priorityLabel).append(priorityAdd).append('</div>');
  4898. resourceSpan.append(priorityControls)
  4899.  
  4900. let minSub = $('<span role="button" aria-label="Decrease '+resources[id].name+' Minimum" class="sub ea-storage-settings" style="width:25%">«</span>');
  4901. minSub.on('mouseup', function(e) {
  4902. if (e.which != 1) {return;}
  4903. resources[id].decStoreMin();
  4904. minLabel[0].removeChild(minLabel[0].firstChild);
  4905. minLabel[0].appendChild(document.createTextNode(resources[id].storeMin));
  4906. });
  4907. let minAdd = $('<span role="button" aria-label="Increase '+resources[id].name+' Minimum" class="add ea-storage-settings" style="width:25%">»</span>');
  4908. minAdd.on('mouseup', function(e) {
  4909. if (e.which != 1) {return;}
  4910. resources[id].incStoreMin();
  4911. minLabel[0].removeChild(minLabel[0].firstChild);
  4912. minLabel[0].appendChild(document.createTextNode(resources[id].storeMin));
  4913. });
  4914. let minLabel = $('<span class="count current" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:30%;text-align:center;">'+resources[id].storeMin+'</span>');
  4915. let minControls = $('<div class="controls ea-storage-settings" style="position:absolute;left:9%;">').append(minSub).append(minLabel).append(minAdd).append('</div>');
  4916. resourceSpan.append(minControls)
  4917. }
  4918. function createStorageSettings() {
  4919. removeStorageSettings();
  4920. // Creating labels
  4921. let labelSpan = $('#resContainers');
  4922. let prioLabel = $('<div class="ea-storage-settings" style="position:absolute;left:6%;"><span class="has-text-warning">Priority</span></div>');
  4923. let minLabel = $('<div class="ea-storage-settings" style="position:absolute;left:10%;"><span class="has-text-warning">Min</span></div>');
  4924. labelSpan.append(prioLabel).append(minLabel);
  4925. // Creating individual counters
  4926. for (let x in resources) {
  4927. createStorageSetting(x);
  4928. }
  4929. // Creating manual button
  4930. let autoStorageBtn = $('<a class="button is-dark is-small ea-storage-settings" id="manualStorage" title="Manual trigger for autoStorage (instead of waiting for automatic check)"><span>Manual</span></a>');
  4931. autoStorageBtn.on('mouseup', function(e){
  4932. if (e.which != 1) {return;}
  4933. autoStorage();
  4934. });
  4935. $('#autoStorage_right').append(autoStorageBtn);
  4936. }
  4937. function removeStorageSettings() {
  4938. $('.ea-storage-settings').remove();
  4939. }
  4940.  
  4941. function createCraftToggle(resource){
  4942. let resourceSpan = $('#res'+resource.id);
  4943. let toggle = $('<label tabindex="0" class="switch ea-craft-settings" style="position:absolute; max-width:75px;margin-top: 4px;left:8%;"><input type="checkbox" value=false> <span class="check" style="height:5px;"></span></label>');
  4944. resourceSpan.append(toggle);
  4945. if(resource.enabled){
  4946. toggle.click();
  4947. toggle.children('input').attr('value', true);
  4948. }
  4949. toggle.on('mouseup', function(e){
  4950. let input = e.currentTarget.children[0];
  4951. let state = !(input.getAttribute('value') === "true");
  4952. input.setAttribute('value', state);
  4953. craftableResources[resource.id].enabled = state;
  4954. });
  4955. }
  4956. function createCraftSettings(){
  4957. removeCraftSettings();
  4958. for (let x in craftableResources) {
  4959. createCraftToggle(craftableResources[x]);
  4960. }
  4961. }
  4962. function removeCraftSettings(){
  4963. $('.ea-craft-settings').remove();
  4964. }
  4965.  
  4966. function createBuildingsTab() {
  4967. let buildingsTabLabel = $('<li class="ea-buildings-tab"><a><span>Buildings</span></a></li>');
  4968. let buildingsTab = $('<div id="buildingsTab" class="tab-item ea-buildings-tab" style="display:none"><h2 class="is-sr-only">Buildings Settings</h2></div>');
  4969. // Creating click functions for other tabs
  4970. for (let i = 1;i <= $('#mainColumn > .content > .b-tabs > .tabs > ul').children().length;i++) {
  4971. let tabLabel = $('#mainColumn > .content > .b-tabs > .tabs > ul > li:nth-child('+i+')');
  4972. let tabItem = $('#mainColumn > .content > .b-tabs > .tab-content').children()[i-1];
  4973. tabLabel.on('mouseup',function(e) {
  4974. if (e.which != 1) {return;}
  4975. if (buildingsTabLabel.hasClass("is-active")) {
  4976. buildingsTabLabel.removeClass("is-active");
  4977. tabItem.style.display = '';
  4978. }
  4979. buildingsTab[0].style.display = 'none';
  4980. if (!tabLabel.hasClass("is-active")) {tabLabel.addClass("is-active");}
  4981. });
  4982. }
  4983. // Inserting Buildings tab after Space tab
  4984. let navTab = $('#mainColumn > .content > .b-tabs > .tabs > ul')[0];
  4985. let conTab = $('#mainColumn > .content > .b-tabs > .tab-content')[0];
  4986. navTab.insertBefore(buildingsTabLabel[0], navTab.children[8]);
  4987. conTab.insertBefore(buildingsTab[0], conTab.children[8]);
  4988. // Creating click function for Buildings tab
  4989. buildingsTabLabel.on('mouseup',function(e) {
  4990. if (e.which != 1) {return;}
  4991. // For every other tab
  4992. for (let i = 1;i <= $('#mainColumn > .content > .b-tabs > .tabs > ul').children().length;i++) {
  4993. let tabLabel = $('#mainColumn > .content > .b-tabs > .tabs > ul > li:nth-child('+i+')');
  4994. let tabItem = $('#mainColumn > .content > .b-tabs > .tab-content').children()[i-1];
  4995. // Ignore Building tab
  4996. if (tabLabel[0].class !== undefined) {
  4997. continue;
  4998. }
  4999. tabLabel.removeClass("is-active");
  5000. tabItem.style.display = 'none';
  5001. }
  5002. buildingsTabLabel.addClass("is-active");
  5003. buildingsTab[0].style.display = '';
  5004. });
  5005.  
  5006. // Creating Smelter Settings
  5007. let smelterLabel = $('<div><h3 class="name has-text-warning" title="Set the smelter settings">Smelter:</h3></div></br>');
  5008. buildingsTab.append(smelterLabel);
  5009.  
  5010. // Creating Factory Settings
  5011. let factoryLabel = $('<div><h3 class="name has-text-warning" title="Set the factory settings">Factory:</h3></div></br>');
  5012. buildingsTab.append(factoryLabel);
  5013.  
  5014. // Creating Building Settings
  5015. let buildingLabel = $('<div><h3 class="name has-text-warning" title="Set the building settings">Buildings:</h3></div></br>');
  5016. buildingsTab.append(buildingLabel);
  5017. let buildSettingsDiv = $('<div id="buildSettingsDiv" style="overflow:auto"></div>');
  5018. let buildSettingsLeft = $('<div id="buildSettingsLeft" style="float:left"></div>');
  5019. let buildSettingsRight = $('<div id="buildSettingsRight" style="float:right"></div>');
  5020.  
  5021. let topLeft = $('<div id="buildSettingsTopLeft"></div>');
  5022. let bottomLeft = $('<div id="buildSettingsBottomLeft"></div>');
  5023. let topRight = $('<div id="buildSettingsTopRight" style="float:right"></div>');
  5024. let bottomRight = $('<div id="buildSettingsBottomRight"></div>');
  5025.  
  5026. let search = $('<input type="text" id="buildingInput" placeholder="Search for buildings (ex: \'iron tag:city res:money\')" style="width:400px;">');
  5027. search.on('input', populateBuildingList);
  5028. let sortLabel = $('<span style="padding-left:20px;padding-right:20px;">Sort:</span>');
  5029. let sort = $('<select style="width:110px;" id="buildingSort"><option value="none">None</option><option value="name">Name</option><option value="priority">Priority</option><option value="power_priority">Power Priority</option></select>');
  5030. sort.on('change', populateBuildingList);
  5031. topLeft.append(search).append(sortLabel).append(sort);
  5032.  
  5033. let showToggle = $('<label tabindex="0" class="switch" id="show_toggle" style=""><input type="checkbox" value=false> <span class="check"></span><span>Show All</span></label>');
  5034. showToggle.on('change', populateBuildingList);
  5035. showToggle.on('mouseup', function(e){
  5036. if (e.which != 1) {return;}
  5037. let input = e.currentTarget.children[0];
  5038. let state = !(input.getAttribute('value') === "true");
  5039. input.setAttribute('value', state);
  5040. });
  5041. bottomLeft.append(showToggle);
  5042.  
  5043. let enableLabel = $('<span style="padding-right:10px;">Enable:</span>');
  5044. let enableAllBtn = $('<a class="button is-dark is-small" id="enable-all-btn"><span>All</span></a>');
  5045. enableAllBtn.on('mouseup', function(e){
  5046. if (e.which != 1) {return;}
  5047. for (let x in buildings) {
  5048. buildings[x].enabled = true;
  5049. }
  5050. populateBuildingList();
  5051. createBuildingSettings();
  5052. });
  5053. let enableVisBtn = $('<a class="button is-dark is-small" id="enable-vis-btn"><span>Visible</span></a>');
  5054. enableVisBtn.on('mouseup', function(e){
  5055. if (e.which != 1) {return;}
  5056. for (let i = 0;i < shownBuildings.length;i++) {
  5057. buildings[shownBuildings[i].id].enabled = true;
  5058. }
  5059. populateBuildingList();
  5060. createBuildingSettings();
  5061. });
  5062. topRight.append(enableLabel).append(enableAllBtn).append(enableVisBtn);
  5063.  
  5064. let disableLabel = $('<span style="padding-right:10px;">Disable:</span>');
  5065. let disableAllBtn = $('<a class="button is-dark is-small" id="disable-all-btn"><span>All</span></a>');
  5066. disableAllBtn.on('mouseup', function(e){
  5067. if (e.which != 1) {return;}
  5068. for (let x in buildings) {
  5069. buildings[x].enabled = false;
  5070. }
  5071. populateBuildingList();
  5072. createBuildingSettings();
  5073. });
  5074. let disableVisBtn = $('<a class="button is-dark is-small" id="disable-vis-btn"><span>Visible</span></a>');
  5075. disableVisBtn.on('mouseup', function(e){
  5076. if (e.which != 1) {return;}
  5077. for (let i = 0;i < shownBuildings.length;i++) {
  5078. buildings[shownBuildings[i].id].enabled = false;
  5079. }
  5080. populateBuildingList();
  5081. createBuildingSettings();
  5082. });
  5083. bottomRight.append(disableLabel).append(disableAllBtn).append(disableVisBtn);
  5084.  
  5085. buildSettingsLeft.append(topLeft).append(bottomLeft);
  5086. buildSettingsRight.append(topRight).append(bottomRight);
  5087. buildSettingsDiv.append(buildSettingsLeft).append(buildSettingsRight);
  5088. buildingsTab.append(buildSettingsDiv);
  5089.  
  5090. let buildingList = $('<div id="buildingList"></div>');
  5091. let buildingListLabel = $(`
  5092. <div style="display:flex;">
  5093. <span class="name has-text-warning" style="width:30%;" title="Building Name. Can be lowercase id if not currently available">Building</span>
  5094. <span class="name has-text-warning" style="width:20%;text-align:center;" title="Will stop building this building after reaching this limit">Limit</span>
  5095. <span class="name has-text-warning" style="width:10%;" title="Enables this building for being automatically built">Enabled</span>
  5096. <span class="name has-text-warning" style="width:20%;text-align:center;" title="Sets the priority of this building to be built">Priority</span>
  5097. <span class="name has-text-warning" style="width:20%;text-align:center;" title="Sets the priority for powering this building">Power Priority</span>
  5098. </div>`);
  5099. buildingList.append(buildingListLabel);
  5100. buildingsTab.append(buildingList);
  5101. populateBuildingList();
  5102. }
  5103. function nameCompare(a, b) {
  5104. return b.id.split('-')[1] < a.id.split('-')[1];
  5105. }
  5106. function priorityCompare(a, b) {
  5107. return b.priority - a.priority;
  5108. }
  5109. function powerCompare(a, b) {
  5110. return b.priority - a.priority;
  5111. }
  5112. let shownBuildings = [];
  5113. function populateBuildingList() {
  5114. let search = $('#buildingInput')[0];
  5115. let sort = $('#buildingSort')[0];
  5116. let showToggle = $('#show_toggle')[0];
  5117. let buildingList = $('#buildingList')[0];
  5118. while(buildingList.childNodes.length != 1) {
  5119. buildingList.removeChild(buildingList.lastChild);
  5120. }
  5121. //console.log("Populating Building List");
  5122. let terms = search.value.split(' ');
  5123. let names = [];
  5124. let tags = [];
  5125. let res = [];
  5126. for (let i = 0;i < terms.length;i++) {
  5127. let tagCheck = /tag:(.+)/.exec(terms[i]);
  5128. let resCheck = /res:(.+)/.exec(terms[i]);
  5129. //console.log(terms[i], tagCheck, resCheck);
  5130. if (tagCheck !== null) {
  5131. tags.push(tagCheck[1]);
  5132. } else if (resCheck !== null) {
  5133. res.push(resCheck[1]);
  5134. } else {
  5135. names.push(terms[i]);
  5136. }
  5137. }
  5138. //console.log(names, tags, res);
  5139. shownBuildings = [];
  5140. for (let x in buildings) {
  5141. let building = buildings[x];
  5142.  
  5143.  
  5144. // Checking if available
  5145. if (showToggle.children[0].value == 'false' && !building.unlocked) {
  5146. continue;
  5147. }
  5148.  
  5149. // Searching for if any names appear in building name
  5150. if (names.length != 0) {
  5151. let pass = false;
  5152. for (let i = 0;i < names.length;i++) {
  5153. let name;
  5154. if (building.name !== null) {
  5155. name = building.name;
  5156. } else {
  5157. name = building.id.split('-')[1];
  5158. }
  5159. if (name.toLowerCase().indexOf(names[i]) >= 0) {
  5160. pass = true;
  5161. break;
  5162. }
  5163. }
  5164. if (!pass) {
  5165. continue;
  5166. }
  5167. }
  5168. // Searching for if any tags appear in building name
  5169. if (tags.length != 0) {
  5170. let pass = false;
  5171. for (let i = 0;i < tags.length;i++) {
  5172. if (building.tags.includes(tags[i])) {
  5173. pass = true;
  5174. break;
  5175. }
  5176. }
  5177. if (!pass) {
  5178. continue;
  5179. }
  5180. }
  5181.  
  5182. // Searching for if any resources appear in building requirements
  5183. if (res.length != 0 && building.res !== null) {
  5184. let pass = false;
  5185. for (let i = 0;i < res.length;i++) {
  5186. if (building.getResDep(res[i]) !== null && building.getResDep(res[i]) > 0) {
  5187. pass = true;
  5188. break;
  5189. }
  5190. }
  5191. if (!pass) {
  5192. continue;
  5193. }
  5194. }
  5195.  
  5196. shownBuildings.push(building);
  5197. }
  5198. //console.log(shownBuildings);
  5199.  
  5200. // Sorting if necessary
  5201. if (sort.value == 'name') {
  5202. shownBuildings.sort(nameCompare);
  5203. } else if (sort.value == 'priority') {
  5204. shownBuildings.sort(priorityCompare);
  5205. } else if (sort.value == 'power_priority') {
  5206. shownBuildings.sort(powerCompare);
  5207. }
  5208.  
  5209. // Drawing buildings into list
  5210. for (let i = 0;i < shownBuildings.length;i++) {
  5211. let building = shownBuildings[i];
  5212. let buildingDiv;
  5213. if (i % 2) {
  5214. buildingDiv = $('<div style="display:flex"></div>');
  5215. } else {
  5216. buildingDiv = $('<div style="display:flex" class="resource alt"></div>');
  5217. }
  5218. buildingList.appendChild(buildingDiv[0]);
  5219.  
  5220. // Name Label
  5221. let name = building.name || building.id.split('-')[1];
  5222.  
  5223. buildingDiv.append($('<span style="width:30%;">'+name+'</span>'));
  5224.  
  5225. // Building Limit
  5226. let limSub = $('<span role="button" aria-label="Decrease Build Limit" class="sub ea-buildings-tab">«</span>');
  5227. limSub.on('mouseup', function(e) {
  5228. buildings[building.id].decLimit();
  5229. let count = $('#'+building.id+'-limit')[0];
  5230. count.removeChild(count.firstChild);
  5231. count.appendChild(document.createTextNode(buildings[building.id].limit));
  5232. });
  5233. let limAdd = $('<span role="button" aria-label="Increase Build Limit" class="add ea-buildings-tab">»</span>');
  5234. limAdd.on('mouseup', function(e) {
  5235. buildings[building.id].incLimit();
  5236. let count = $('#'+building.id+'-limit')[0];
  5237. count.removeChild(count.firstChild);
  5238. count.appendChild(document.createTextNode(buildings[building.id].limit));
  5239. });
  5240. let limLabel = $('<span class="count current" id="'+building.id+'-limit" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:2rem;">'+buildings[building.id].limit+'</span>');
  5241. let limControls = $('<div class="controls ea-buildings-tab" style="width:20%;text-align:center;">').append(limSub).append(limLabel).append(limAdd).append('</div>');
  5242. buildingDiv.append(limControls);
  5243.  
  5244. // Building Toggle
  5245. let toggle = $('<label tabindex="0" class="switch ea-buildings-tab" style="margin-top: 4px;width:10%;"><input type="checkbox" value=false> <span class="check" style="height:5px;"></span></label>');
  5246. buildingDiv.append(toggle);
  5247. if(buildings[building.id].enabled){
  5248. toggle.click();
  5249. toggle.children('input').attr('value', true);
  5250. }
  5251. toggle.on('mouseup', function(e){
  5252. if (e.which != 1) {return;}
  5253. let input = e.currentTarget.children[0];
  5254. let state = !(input.getAttribute('value') === "true");
  5255. console.log("Updated build state", building.id, state);
  5256. input.setAttribute('value', state);
  5257. buildings[building.id].enabled = state;
  5258. createBuildingSettings();
  5259. });
  5260.  
  5261. // Building Priority
  5262. let prioSub = $('<span role="button" aria-label="Decrease Build Priority" class="sub ea-buildings-tab">«</span>');
  5263. prioSub.on('mouseup', function(e) {
  5264. buildings[building.id].decPriority();
  5265. let count = $('#'+building.id+'-prio')[0];
  5266. count.removeChild(count.firstChild);
  5267. count.appendChild(document.createTextNode(buildings[building.id].priority));
  5268. });
  5269. let prioAdd = $('<span role="button" aria-label="Increase Build Priority" class="add ea-buildings-tab">»</span>');
  5270. prioAdd.on('mouseup', function(e) {
  5271. buildings[building.id].incPriority();
  5272. let count = $('#'+building.id+'-prio')[0];
  5273. count.removeChild(count.firstChild);
  5274. count.appendChild(document.createTextNode(buildings[building.id].priority));
  5275. });
  5276. let prioLabel = $('<span class="count current" id="'+building.id+'-prio" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:2rem;">'+buildings[building.id].priority+'</span>');
  5277. let prioControls = $('<div class="controls ea-buildings-tab" style="width:20%;text-align:center;">').append(prioSub).append(prioLabel).append(prioAdd).append('</div>');
  5278. buildingDiv.append(prioControls);
  5279.  
  5280. // Power Priority
  5281. if (building.hasOwnProperty('power_priority')) {
  5282. let powerSub = $('<span role="button" aria-label="Decrease Power Priority" class="sub ea-buildings-tab">«</span>');
  5283. powerSub.on('mouseup', function(e) {
  5284. buildings[building.id].decPowerPriority();
  5285. let count = $('#'+building.id+'-power-prio')[0];
  5286. count.removeChild(count.firstChild);
  5287. count.appendChild(document.createTextNode(buildings[building.id].powerPriority));
  5288. });
  5289. let powerAdd = $('<span role="button" aria-label="Increase Power Priority" class="add ea-buildings-tab">»</span>');
  5290. powerAdd.on('mouseup', function(e) {
  5291. buildings[building.id].incPowerPriority();
  5292. let count = $('#'+building.id+'-power-prio')[0];
  5293. count.removeChild(count.firstChild);
  5294. count.appendChild(document.createTextNode(buildings[building.id].powerPriority));
  5295. });
  5296. let powerLabel = $('<span class="count current" id="'+building.id+'-power-prio" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:2rem;">'+buildings[building.id].powerPriority+'</span>');
  5297. let powerControls = $('<div class="controls ea-buildings-tab" style="width:20%;text-align:center;">').append(powerSub).append(powerLabel).append(powerAdd).append('</div>');
  5298. buildingDiv.append(powerControls);
  5299. }
  5300.  
  5301. }
  5302.  
  5303. // Set focus back on search
  5304. search.focus();
  5305. }
  5306.  
  5307. function createBuildingToggle(building){
  5308. return;
  5309. var key;
  5310. let batElmt = $('#'+building.id);
  5311. let toggle = $('<label tabindex="0" class="switch ea-building-settings" style="position:absolute; margin-top: 30px;left:13%;top:-13%;"><input type="checkbox" value=false> <span class="check" style="height:5px; max-width:15px"></span></label>');
  5312. batElmt.append(toggle);
  5313. if(buildings[building.id].enabled){
  5314. toggle.click();
  5315. toggle.children('input').attr('value', true);
  5316. }
  5317. toggle.on('mouseup', function(e){
  5318. if (e.which != 1) {return;}
  5319. let input = e.currentTarget.children[0];
  5320. let state = !(input.getAttribute('value') === "true");
  5321. input.setAttribute('value', state);
  5322. buildings[building.id].enabled = state;
  5323. });
  5324. }
  5325. function createBuildingSettings(){
  5326. removeBuildingSettings();
  5327. // Creating building toggles for Village and Space tabs
  5328. for (let x in buildings) {
  5329. if (buildings[x].unlocked) {
  5330. createBuildingToggle(buildings[x]);
  5331. }
  5332. }
  5333.  
  5334. // Create generic Build All button for main settings div
  5335. let buildAllBtn = $('<a class="button is-dark is-small ea-building-settings" id="build-all"><span>Set All</span></a>');
  5336. buildAllBtn.on('mouseup', function(e){
  5337. if (e.which != 1) {return;}
  5338. for (let x in buildings) {
  5339. buildings[x].enabled = true;
  5340. }
  5341. populateBuildingList();
  5342. createBuildingSettings();
  5343. });
  5344. // Create generic Build None button for main settings div
  5345. let buildNoneBtn = $('<a class="button is-dark is-small ea-building-settings" id="build-all"><span>Set None</span></a>');
  5346. buildNoneBtn.on('mouseup', function(e){
  5347. if (e.which != 1) {return;}
  5348. for (let x in buildings) {
  5349. buildings[x].enabled = false;
  5350. }
  5351. populateBuildingList();
  5352. createBuildingSettings();
  5353. });
  5354. $('#autoBuild_right').append(buildAllBtn).append(buildNoneBtn);
  5355. }
  5356. function removeBuildingSettings(){
  5357. $('.ea-building-settings').remove();
  5358. }
  5359.  
  5360. function createSmelterSettings() {
  5361. removeSmelterSettings();
  5362. // Create manual button for Auto Smelting
  5363. let autoSmelterBtn = $('<a class="button is-dark is-small ea-smelter-settings" id="smelter-manual"><span>Manual</span></a>');
  5364. autoSmelterBtn.on('mouseup', function(e){
  5365. if (e.which != 1) {return;}
  5366. autoSmelter();
  5367. });
  5368. $('#autoSmelter_right').append(autoSmelterBtn);
  5369. }
  5370. function removeSmelterSettings() {
  5371. $('.ea-smelter-settings').remove();
  5372. }
  5373.  
  5374. function createFactorySettings() {
  5375. removeSmelterSettings();
  5376. // Create manual button for Auto Smelting
  5377. let autoBtn = $('<a class="button is-dark is-small ea-factory-settings" id="factory-manual"><span>Manual</span></a>');
  5378. autoBtn.on('mouseup', function(e){
  5379. if (e.which != 1) {return;}
  5380. autoFactory();
  5381. });
  5382. $('#autoFactory_right').append(autoBtn);
  5383. }
  5384. function removeFactorySettings() {
  5385. $('.ea-factory-settings').remove();
  5386. }
  5387.  
  5388. function createSupportSettings() {
  5389. let supportTabLabel = $('<li class="ea-support-settings"><a><span>Support</span></a></li>');
  5390. let supportTab = $('<div id="supportSettings" class="tab-item ea-support-settings" style="display:none"><h2 class="is-sr-only">Auto Support Settings</h2></div>');
  5391. // Creating click functions for other tabs
  5392. for (let i = 1;i <= $('#mainColumn > .content > .b-tabs > .tabs > ul').children().length;i++) {
  5393. let tabLabel = $('#mainColumn > .content > .b-tabs > .tabs > ul > li:nth-child('+i+')');
  5394. let tabItem = $('#mainColumn > .content > .b-tabs > .tab-content').children()[i-1];
  5395. tabLabel.on('mouseup',function(e) {
  5396. if (e.which != 1) {return;}
  5397. if (supportTabLabel.hasClass("is-active")) {
  5398. supportTabLabel.removeClass("is-active");
  5399. tabItem.style.display = '';
  5400. }
  5401. supportTab[0].style.display = 'none';
  5402. if (!tabLabel.hasClass("is-active")) {tabLabel.addClass("is-active");}
  5403. });
  5404. }
  5405. $('#mainColumn > .content > .b-tabs > .tabs > ul').append(supportTabLabel);
  5406. $('#mainColumn > .content > .b-tabs > .tab-content').append(supportTab);
  5407. supportTabLabel.on('mouseup',function(e) {
  5408. if (e.which != 1) {return;}
  5409. // For every other tab
  5410. for (let i = 1;i <= $('#mainColumn > .content > .b-tabs > .tabs > ul').children().length-1;i++) {
  5411. let tabLabel = $('#mainColumn > .content > .b-tabs > .tabs > ul > li:nth-child('+i+')');
  5412. let tabItem = $('#mainColumn > .content > .b-tabs > .tab-content').children()[i-1];
  5413. tabLabel.removeClass("is-active");
  5414. tabItem.style.display = 'none';
  5415. }
  5416. supportTabLabel.addClass("is-active");
  5417. supportTab[0].style.display = '';
  5418. });
  5419. // Filling support tab
  5420. if(researched('tech-electricity')) {
  5421. let label = $('<div><h3 class="name has-text-warning" title="Set the priority of buildings that require electricity">Electricity:</h3></div>');
  5422. supportTab.append(label);
  5423. for (let x in elecConsumers) {
  5424. let c = elecConsumers[x];
  5425. if (!c.unlocked) {continue;}
  5426. let btnDiv = $('<div class="action cna"></div>');
  5427. let btnLabel = $('<a class="button is-dark"><span class="aTitle">'+c.name+'</span><span class="count" title="'+c.name+' Priority">'+c.priority+'</span></a>');
  5428. let btnInc = $('<span role="button" title="Increase '+c.name+' Priority" class="on">+</span>');
  5429. let btnDec = $('<span role="button" title="Decrease '+c.name+' Priority" class="off">-</span>');
  5430. btnDec.on('mouseup',function(e) {
  5431. if (e.which != 1) {return;}
  5432. elecConsumers[c.name].lowerPriority();
  5433. btnLabel[0].children[1].innerText = elecConsumers[c.name].priority;
  5434. updateSettings();
  5435. });
  5436. btnInc.on('mouseup',function(e) {
  5437. if (e.which != 1) {return;}
  5438. elecConsumers[c.name].higherPriority();
  5439. btnLabel[0].children[1].innerText = elecConsumers[c.name].priority;
  5440. updateSettings();
  5441. });
  5442. btnDiv.append(btnLabel).append(btnDec).append(btnInc);
  5443. supportTab.append(btnDiv);
  5444. }
  5445. }
  5446. }
  5447. function removeSupportSettings() {
  5448. $('.ea-support-settings').remove();
  5449. }
  5450.  
  5451. function createMarketSetting(resource){
  5452. let marketRow = $('#market-'+resource.id);
  5453.  
  5454. let toggleBuy = $('<label tabindex="0" class="switch ea-market-settings" style=""><input type="checkbox" value=false> <span class="check" style="height:5px;"></span><span class="control-label" style="font-size: small;">auto buy</span><span class="state"></span></label>');
  5455. let buyRatioLabel = $('<span class="ea-market-settings count current" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:2.5rem;font-size:.8rem">(&lt'+resource.buyRatio+')</span>');
  5456. let buyRatioSub = $('<span role="button" aria-label="Decrease '+resource.name+' Buy Ratio" class="sub ea-market-settings">«</span>');
  5457. buyRatioSub.on('mouseup', function(e) {
  5458. if (e.which != 1) {return;}
  5459. resource.buyDec();
  5460. buyRatioLabel[0].removeChild(buyRatioLabel[0].firstChild);
  5461. buyRatioLabel[0].appendChild(document.createTextNode('(<'+resource.buyRatio+')'));
  5462. });
  5463. let buyRatioAdd = $('<span role="button" aria-label="Increase '+resource.name+' Buy Ratio" class="add ea-market-settings">»</span>');
  5464. buyRatioAdd.on('mouseup', function(e) {
  5465. if (e.which != 1) {return;}
  5466. resource.buyInc();
  5467. buyRatioLabel[0].removeChild(buyRatioLabel[0].firstChild);
  5468. buyRatioLabel[0].appendChild(document.createTextNode('(<'+resource.buyRatio+')'));
  5469. });
  5470. marketRow.append(toggleBuy);
  5471. marketRow.append(buyRatioSub).append(buyRatioLabel).append(buyRatioAdd);
  5472.  
  5473. let toggleSell = $('<label tabindex="0" class="switch ea-market-settings" style=""><input type="checkbox" value=false> <span class="check" style="height:5px;"></span><span class="control-label" style="font-size: small;">auto sell</span><span class="state"></span></label>');
  5474. let sellRatioLabel = $('<span class="ea-market-settings count current" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:2.5rem;font-size:.8rem">(&gt'+resource.sellRatio+')</span>');
  5475. let sellRatioSub = $('<span role="button" aria-label="Decrease '+resource.name+' Sell Ratio" class="sub ea-market-settings">«</span>');
  5476. sellRatioSub.on('mouseup', function(e) {
  5477. if (e.which != 1) {return;}
  5478. resource.sellDec();
  5479. sellRatioLabel[0].removeChild(sellRatioLabel[0].firstChild);
  5480. sellRatioLabel[0].appendChild(document.createTextNode('(>'+resource.sellRatio+')'));
  5481. });
  5482. let sellRatioAdd = $('<span role="button" aria-label="Increase '+resource.name+' Sell Ratio" class="add ea-market-settings">»</span>');
  5483. sellRatioAdd.on('mouseup', function(e) {
  5484. if (e.which != 1) {return;}
  5485. resource.sellInc();
  5486. sellRatioLabel[0].removeChild(sellRatioLabel[0].firstChild);
  5487. sellRatioLabel[0].appendChild(document.createTextNode('(>'+resource.sellRatio+')'));
  5488. });
  5489. marketRow.append(toggleSell);
  5490. marketRow.append(sellRatioSub).append(sellRatioLabel).append(sellRatioAdd);
  5491.  
  5492. if(resource.autoBuy){
  5493. toggleBuy.click();
  5494. toggleBuy.children('input').attr('value', true);
  5495. }
  5496. if(resource.autoSell){
  5497. toggleSell.click();
  5498. toggleSell.children('input').attr('value', true);
  5499. }
  5500. toggleBuy.on('mouseup', function(e){
  5501. if (e.which != 1) {return;}
  5502. let input = e.currentTarget.children[0];
  5503. let state = !(input.getAttribute('value') === "true");
  5504. input.setAttribute('value', state);
  5505. resources[resource.id].autoBuy = state;
  5506. let otherState = toggleSell.children('input').attr('value') === 'true';
  5507. if(state && otherState){
  5508. toggleSell.click();
  5509. console.log("Turning off toggleSell");
  5510. resources[resource.id].autoSell = false;
  5511. toggleSell.children('input')[0].setAttribute('value',false);
  5512. }
  5513. resources[resource.id].autoBuy = state;
  5514. updateSettings();
  5515. });
  5516. toggleSell.on('mouseup', function(e){
  5517. if (e.which != 1) {return;}
  5518. let input = e.currentTarget.children[0];
  5519. let state = !(input.getAttribute('value') === "true");
  5520. input.setAttribute('value', state);
  5521. resources[resource.id].autoSell = state;
  5522. let otherState = toggleBuy.children('input').attr('value') === 'true';
  5523. if(state && otherState){
  5524. toggleBuy.click();
  5525. console.log("Turning off toggleBuy");
  5526. resources[resource.id].autoBuy = false;
  5527. toggleBuy.children('input')[0].setAttribute('value',false);
  5528. }
  5529. updateSettings();
  5530. });
  5531.  
  5532. if($('#bulk-sell').length == 0 && researched('tech-market')){
  5533. let bulkSell = $('<a class="ea-market-settings button is-dark is-small" id="bulk-sell"><span>Bulk Sell</span></a>');
  5534. $('#autoMarket_right').append(bulkSell);
  5535. bulkSell.on('mouseup', function(e){
  5536. if (e.which != 1) {return;}
  5537. autoMarket(true, true);
  5538. });
  5539. }
  5540. }
  5541. function createMarketSettings(){
  5542. removeMarketSettings();
  5543. for (let x in resources) {
  5544. createMarketSetting(resources[x]);
  5545. }
  5546. }
  5547. function removeMarketSettings(){
  5548. $('.ea-market-settings').remove();
  5549. }
  5550.  
  5551. function createEmploySettings() {
  5552. removeEmploySettings();
  5553. for (let x in jobs) {
  5554. let job = jobs[x];
  5555. if (!job.unlocked) {continue;}
  5556.  
  5557. if (job.id != "free" || job.name == 'Hunter') {
  5558. if (job.id == "craftsman") {
  5559. let prioritySub = $('<span role="button" aria-label="Decrease '+job.name+' Priority" class="sub ea-employ-craft-settings">«</span>');
  5560. prioritySub.on('mouseup', function(e) {
  5561. autoEmployer.lowerPriority(jobs[job.id]);
  5562. });
  5563. let priorityAdd = $('<span role="button" aria-label="Increase '+job.name+' Priority" class="add ea-employ-craft-settings">»</span>');
  5564. priorityAdd.on('mouseup', function(e) {
  5565. autoEmployer.higherPriority(jobs[job.id]);
  5566. });
  5567. let priorityLabel = $('<span class="count current" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:1.5rem;">'+job.priority+'</span>');
  5568. let priorityControls = $('<div class="foundry controls ea-employ-craft-settings" style="text-align:right;min-width:9.25rem;">').append(prioritySub).append(priorityLabel).append(priorityAdd).append('</div>');
  5569. let parent = $('#foundry > .job > .foundry').parent();
  5570. parent.append(priorityControls);
  5571. } else if (job.id == 'free') {
  5572. let prioritySub = $('<span role="button" aria-label="Decrease '+job.name+' Priority" class="sub ea-employ-settings">«</span>');
  5573. prioritySub.on('mouseup', function(e) {
  5574. autoEmployer.lowerPriority(jobs[job.id]);
  5575. });
  5576. let priorityAdd = $('<span role="button" aria-label="Increase '+job.name+' Priority" class="add ea-employ-settings">»</span>');
  5577. priorityAdd.on('mouseup', function(e) {
  5578. autoEmployer.higherPriority(jobs[job.id]);
  5579. });
  5580. let priorityLabel = $('<span class="count current" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:1.5rem;">'+job.priority+'</span>');
  5581. let priorityControls = $('<div class="controls ea-employ-settings" style="text-align:right;min-width:9.25rem;">').append(prioritySub).append(priorityLabel).append(priorityAdd).append('</div>');
  5582. $('#civ-'+job.id).append(priorityControls)
  5583. }else {
  5584. let prioritySub = $('<span role="button" aria-label="Decrease '+job.name+' Priority" class="sub ea-employ-settings">«</span>');
  5585. prioritySub.on('mouseup', function(e) {
  5586. autoEmployer.lowerPriority(jobs[job.id]);
  5587. });
  5588. let priorityAdd = $('<span role="button" aria-label="Increase '+job.name+' Priority" class="add ea-employ-settings">»</span>');
  5589. priorityAdd.on('mouseup', function(e) {
  5590. autoEmployer.higherPriority(jobs[job.id]);
  5591. });
  5592. let priorityLabel = $('<span class="count current" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:1.5rem;">'+job.priority+'</span>');
  5593. let priorityControls = $('<div class="controls ea-employ-settings" style="text-align:right;min-width:6rem;">').append(prioritySub).append(priorityLabel).append(priorityAdd).append('</div>');
  5594. $('#civ-'+job.id).append(priorityControls)
  5595. }
  5596.  
  5597. } else {
  5598. let parent = document.getElementById("civ-"+job.id);
  5599. let priorityLabel = $('<span class="has-text-warning ea-employ-settings" style="text-align:right;min-width:9.25rem">Priority</span>');
  5600. $('#civ-'+job.id).append(priorityLabel);
  5601. }
  5602. }
  5603. for (let x in craftJobs) {
  5604. let cjob = craftJobs[x];
  5605. if (!cjob.unlocked) {continue;}
  5606. let prioritySub = $('<span role="button" aria-label="Decrease '+cjob.name+' Priority" class="sub ea-employ-craft-settings">«</span>');
  5607. prioritySub.on('mouseup', function(e) {
  5608. autoEmployer.lowerPriority(craftJobs[cjob.id]);
  5609. });
  5610. let priorityAdd = $('<span role="button" aria-label="Increase '+cjob.name+' Priority" class="add ea-employ-craft-settings">»</span>');
  5611. priorityAdd.on('mouseup', function(e) {
  5612. autoEmployer.higherPriority(craftJobs[cjob.id]);
  5613. });
  5614. let priorityLabel = $('<span class="count current" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:1.5rem;">'+cjob.priority+'</span>');
  5615. let priorityControls = $('<div class="controls ea-employ-craft-settings" style="text-align:right;min-width:6rem;">').append(prioritySub).append(priorityLabel).append(priorityAdd).append('</div>');
  5616. $('#craft'+cjob.id).parent().append(priorityControls)
  5617. }
  5618. }
  5619. function removeEmploySettings() {
  5620. $('.ea-employ-settings').remove();
  5621. $('.ea-employ-craft-settings').remove();
  5622. }
  5623.  
  5624. function createTaxSettings() {
  5625. let moraleText = $('<span>Set Default Morale:</span>');
  5626. let moraleSub = $('<span role="button" aria-label="Decrease Morale" class="sub ea-tax-settings">«</span>');
  5627. moraleSub.on('mouseup', function(e) {
  5628. settings.defaultMorale -= 1;
  5629. let count = $('#autoTax > div > .ea-tax-settings > .count')[0];
  5630. count.removeChild(count.firstChild);
  5631. count.appendChild(document.createTextNode(settings.defaultMorale));
  5632. updateSettings();
  5633. });
  5634. let moraleAdd = $('<span role="button" aria-label="Increase Morale" class="add ea-tax-settings">»</span>');
  5635. moraleAdd.on('mouseup', function(e) {
  5636. settings.defaultMorale += 1;
  5637. let count = $('#autoTax > div > .ea-tax-settings > .count')[0];
  5638. count.removeChild(count.firstChild);
  5639. count.appendChild(document.createTextNode(settings.defaultMorale));
  5640. updateSettings();
  5641. });
  5642. let moraleLabel = $('<span class="count current" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:3rem;">'+settings.defaultMorale+'</span>');
  5643. let moraleControls = $('<div class="controls ea-tax-settings" style="text-align:right;min-width:6rem;">').append(moraleText).append(moraleSub).append(moraleLabel).append(moraleAdd).append('</div>');
  5644. $('#autoTax_right').append(moraleControls);
  5645. }
  5646. function removeTaxSettings() {
  5647. $('.ea-tax-settings').remove();
  5648. }
  5649.  
  5650. function createResearchTab() {
  5651. // Creating Auto Research Tab
  5652. let researchSettingTabLabel = $('<li class="ea-research-tab"><a><span>Auto Settings</span></a></li>');
  5653. let newTab = $('.resTabs > .tabs > ul > li:nth-child(1)');
  5654. let completeTab = $('.resTabs > .tabs > ul > li:nth-child(2)');
  5655. let newTabItem = $('#tech');
  5656. let completeTabItem = $('#oldTech');
  5657. let resTabs = $($('.resTabs')[1]);
  5658. resTabs.find('> .tabs > ul').append(researchSettingTabLabel);
  5659. let researchSettingTab = $('<div id="researchSettings" class="tab-item ea-research-tab" style="display:none"><h2 class="is-sr-only">Auto Research Settings</h2></div>');
  5660. resTabs.find('> .tab-content').append(researchSettingTab);
  5661. newTab.on('mouseup',function(e) {
  5662. if (e.which != 1) {return;}
  5663. if (researchSettingTabLabel.hasClass("is-active")) {
  5664. researchSettingTabLabel.removeClass("is-active");
  5665. newTabItem[0].style.display = '';
  5666. }
  5667. researchSettingTab[0].style.display = 'none';
  5668. if (!newTab.hasClass("is-active")) {newTab.addClass("is-active");}
  5669. });
  5670. completeTab.on('mouseup',function(e) {
  5671. if (e.which != 1) {return;}
  5672. if (researchSettingTabLabel.hasClass("is-active")) {
  5673. researchSettingTabLabel.removeClass("is-active");
  5674. completeTabItem[0].style.display = '';
  5675. }
  5676. researchSettingTab[0].style.display = 'none';
  5677. if (!completeTab.hasClass("is-active")) {completeTab.addClass("is-active");}
  5678. });
  5679. researchSettingTabLabel.on('mouseup',function(e) {
  5680. if (e.which != 1) {return;}
  5681. newTab.removeClass("is-active");
  5682. completeTab.removeClass("is-active");
  5683. newTabItem[0].style.display = 'none';
  5684. completeTabItem[0].style.display = 'none';
  5685. researchSettingTabLabel.addClass("is-active");
  5686. researchSettingTab[0].style.display = '';
  5687. });
  5688.  
  5689. // Creating Fanaticism/Anthropology choice
  5690. let label = $('<div><h3 class="name has-text-warning" title="Research choices that give different effects based on the previous runs">Theology:</h3></div></br>');
  5691. let fanORanth = $('<select style="width:150px;"><option value="fanaticism">Fanaticism</option><option value="anthropology">Anthropology</option></select>');
  5692. let fanDesc = "Gain a dominant trait from your progenitor race. If same race, gain a random minor trait. Gives bonuses to combat and trade. Better for long runs.";
  5693. let anthDesc = "Gives bonuses to science and tax income. Better for short runs.";
  5694. let target1 = $('<div style="padding-left:5%;display:flex;"><span style="width:4rem">Target 1:</span></div>');
  5695. target1.append(fanORanth);
  5696. fanORanth[0].value = settings.fanORanth;
  5697. if (settings.fanORanth == "anthropology") {
  5698. fanORanth[0].title = anthDesc;
  5699. } else {
  5700. fanORanth[0].title = fanDesc;
  5701. }
  5702. fanORanth[0].onchange = function(){
  5703. settings.fanORanth = fanORanth[0].value;
  5704. if (settings.fanORanth == "anthropology") {
  5705. fanORanth[0].title = anthDesc;
  5706. } else {
  5707. fanORanth[0].title = fanDesc;
  5708. }
  5709. console.log("Changing target to ", settings.fanORanth);
  5710. updateSettings();
  5711. };
  5712.  
  5713. // Creating Study/Deify choice
  5714. let studyORdeify = $('<select style="width:150px;"><option value="study">Study</option><option value="deify">Deify</option></select>');
  5715. let deifyDesc = "Gain a dominant trait from your progenitor's progenitor race. If same race, gain a random minor trait. Gives bonuses to combat and trade. Better for long runs.";
  5716. let studyDesc = "Gives bonuses to science and tax income. Better for short runs.";
  5717. let target2 = $('<div style="padding-left:5%;display:flex;"><span style="width:4rem">Target 2:</span></div>');
  5718. target2.append(studyORdeify);
  5719. studyORdeify[0].value = settings.studyORdeify;
  5720. if (settings.studyORdeify == "study") {
  5721. studyORdeify[0].title = studyDesc;
  5722. } else {
  5723. studyORdeify[0].title = deifyDesc;
  5724. }
  5725. studyORdeify[0].onchange = function(){
  5726. settings.studyORdeify = studyORdeify[0].value;
  5727. if (settings.studyORdeify == "study") {
  5728. studyORdeify[0].title = studyDesc;
  5729. } else {
  5730. studyORdeify[0].title = deifyDesc;
  5731. }
  5732. console.log("Changing target to ", settings.studyORdeify);
  5733. updateSettings();
  5734. };
  5735. researchSettingTab.append(label).append(target1).append(target2);
  5736. let label2 = $('<div><h3 class="name has-text-warning" title="Research choice that either gives morale boost or production increase">Unification:</h3></div></br>');
  5737. let uniChoice = $('<select style="width:150px;"><option value="conquest">Conquest</option><option value="morale">Morale</option><option value="money">Money</option><option value="reject">Reject</option></select>');
  5738. let target3 = $('<div style="padding-left:5%;display:flex;"><span style="width:4rem;">Choice: </span></div>');
  5739. target3.append(uniChoice);
  5740. uniChoice[0].value = settings.uniChoice;
  5741. uniChoice[0].onchange = function(){
  5742. settings.uniChoice = uniChoice[0].value;
  5743. console.log("Changing target to ", settings.uniChoice);
  5744. updateSettings();
  5745. };
  5746. researchSettingTab.append(label2).append(target3);
  5747.  
  5748. // Creating research list
  5749. let label3 = $('<div><h3 class="name has-text-warning" title="Research list and priorities">Research List:</h3></div></br>');
  5750. researchSettingTab.append(label3);
  5751.  
  5752. let listParamDiv = $('<div id="listParamDiv" style="overflow:auto"></div>');
  5753. let listParamLeft = $('<div id="listParamLeft" style="float:left"></div>');
  5754. let listParamRight = $('<div id="listParamRight" style="float:right"></div>');
  5755.  
  5756. let topLeft = $('<div id="listParamTopLeft"></div>');
  5757. let bottomLeft = $('<div id="listParamBottomLeft"></div>');
  5758. let topRight = $('<div id="listParamTopRight" style="float:right"></div>');
  5759. let bottomRight = $('<div id="listParamBottomRight"></div>');
  5760.  
  5761. let search = $('<input type="text" id="researchInput" placeholder="Search for research (ex: \'crate tag:mine res:knowledge\')" style="width:400px;">');
  5762. search.on('input', populateResearchList);
  5763. let sortLabel = $('<span style="padding-left:20px;padding-right:20px;">Sort:</span>');
  5764. let sort = $('<select style="width:110px;" id="researchSort"><option value="none">None</option><option value="name">Name</option><option value="priority">Priority</option></select>');
  5765. sort.on('change', populateResearchList);
  5766. topLeft.append(search).append(sortLabel).append(sort);
  5767.  
  5768. let showToggle = $('<label tabindex="0" class="switch" id="show_research_toggle" style=""><input type="checkbox" value=false> <span class="check"></span><span>Show All</span></label>');
  5769. showToggle.on('change', populateResearchList);
  5770. showToggle.on('mouseup', function(e){
  5771. if (e.which != 1) {return;}
  5772. let input = e.currentTarget.children[0];
  5773. let state = !(input.getAttribute('value') === "true");
  5774. input.setAttribute('value', state);
  5775. });
  5776. bottomLeft.append(showToggle);
  5777.  
  5778. listParamLeft.append(topLeft).append(bottomLeft);
  5779. listParamRight.append(topRight).append(bottomRight);
  5780. listParamDiv.append(listParamLeft).append(listParamRight);
  5781. researchSettingTab.append(listParamDiv);
  5782.  
  5783. let researchList = $('<div id="researchList"></div>');
  5784. let researchListLabel = $(`
  5785. <div style="display:flex;">
  5786. <span class="name has-text-warning" style="width:30%;" title="Research Name. Can be lowercase id if not currently available">Research</span>
  5787. <span class="name has-text-warning" style="width:20%;text-align:center;" title="Sets the priority of this building to be built">Priority</span>
  5788. </div>`);
  5789. researchList.append(researchListLabel);
  5790. researchSettingTab.append(researchList);
  5791. populateResearchList();
  5792. }
  5793. let shownResearches = [];
  5794. function populateResearchList() {
  5795. return //IMPORTANT. 1.0.21 broke this function in some way. No auto-research possible (not that I used it anyways though)
  5796. let search = $('#researchInput')[0];
  5797. let sort = $('#researchSort')[0];
  5798. let showToggle = $('#show_research_toggle')[0];
  5799. let researchList = $('#researchList')[0];
  5800. while(researchList && researchList.childNodes.length != 1) {
  5801. researchList.removeChild(researchList.lastChild);
  5802. }
  5803. //console.log("Populating Research List");
  5804. let terms = search.value.split(' ');
  5805. let names = [];
  5806. let tags = [];
  5807. let res = [];
  5808. for (let i = 0;i < terms.length;i++) {
  5809. let tagCheck = /tag:(.+)/.exec(terms[i]);
  5810. let resCheck = /res:(.+)/.exec(terms[i]);
  5811. //console.log(terms[i], tagCheck, resCheck);
  5812. if (tagCheck !== null) {
  5813. tags.push(tagCheck[1]);
  5814. } else if (resCheck !== null) {
  5815. res.push(resCheck[1]);
  5816. } else {
  5817. names.push(terms[i]);
  5818. }
  5819. }
  5820. //console.log(names, tags, res);
  5821. shownResearches = [];
  5822. let temp_r = [];
  5823. for (var x in researches) {temp_r.push(researches[x])}
  5824. for (x in arpas) {temp_r.push(arpas[x]);}
  5825. for (let i = 0;i < temp_r.length;i++) {
  5826. let research = temp_r[i];
  5827.  
  5828. // Checking if available
  5829. if (showToggle.children[0].value == 'false' &&!research.unlocked) {
  5830. continue;
  5831. }
  5832. // Searching for if any names appear in building name
  5833. if (names.length != 0) {
  5834. let pass = false;
  5835. for (let i = 0;i < names.length;i++) {
  5836. var name;
  5837. if (research.name !== null) {
  5838. name = research.name;
  5839. } else {
  5840. name = research.id.split('-')[1];
  5841. }
  5842. if (name.toLowerCase().indexOf(names[i]) >= 0) {
  5843. pass = true;
  5844. break;
  5845. }
  5846. }
  5847. if (!pass) {
  5848. continue;
  5849. }
  5850. }
  5851. // Searching for if any tags appear in research name
  5852. if (tags.length != 0) {
  5853. let pass = false;
  5854. for (let i = 0;i < tags.length;i++) {
  5855. if (research.tags.includes(tags[i])) {
  5856. pass = true;
  5857. break;
  5858. }
  5859. }
  5860. if (!pass) {
  5861. continue;
  5862. }
  5863. }
  5864. // Searching for if any resources appear in research requirements
  5865. if (res.length != 0 && research.res !== null) {
  5866. let pass = false;
  5867. for (let i = 0;i < res.length;i++) {
  5868. if (research.getResDep(res[i]) !== null && research.getResDep(res[i]) > 0) {
  5869. pass = true;
  5870. break;
  5871. }
  5872. }
  5873. if (!pass) {
  5874. continue;
  5875. }
  5876. }
  5877.  
  5878. shownResearches.push(research);
  5879. }
  5880.  
  5881. // Sorting if necessary
  5882. if (sort.value == 'name') {
  5883. shownResearches.sort(nameCompare);
  5884. } else if (sort.value == 'priority') {
  5885. shownResearches.sort(priorityCompare);
  5886. }
  5887.  
  5888. // Drawing buildings into list
  5889. for (let i = 0;i < shownResearches.length;i++) {
  5890. let research = shownResearches[i];
  5891. var researchDiv;
  5892. if (i % 2) {
  5893. researchDiv = $('<div style="display:flex"></div>');
  5894. } else {
  5895. researchDiv = $('<div style="display:flex" class="resource alt"></div>');
  5896. }
  5897. researchList.appendChild(researchDiv[0]);
  5898.  
  5899. // Name Label
  5900. if (research.name === null) {
  5901. name = research.id.split('-')[1];
  5902. } else {
  5903. name = research.name;
  5904. }
  5905. researchDiv.append($('<span style="width:30%;">'+name+'</span>'));
  5906.  
  5907. // Research Priority
  5908. let prioSub = $('<span role="button" aria-label="Decrease Research Priority" class="sub ea-research-tab">«</span>');
  5909. prioSub.on('mouseup', function(e) {
  5910. if (research.tags.includes('arpa')) {
  5911. arpas[research.id].decPriority();
  5912. } else {
  5913. researches[research.id].decPriority();
  5914. }
  5915. let count = $('#'+research.id+'-prio')[0];
  5916. count.removeChild(count.firstChild);
  5917. if (research.tags.includes('arpa')) {
  5918. count.appendChild(document.createTextNode(arpas[research.id].priority));
  5919. } else {
  5920. count.appendChild(document.createTextNode(researches[research.id].priority));
  5921. }
  5922. });
  5923. let prioAdd = $('<span role="button" aria-label="Increase Research Priority" class="add ea-research-tab">»</span>');
  5924. prioAdd.on('mouseup', function(e) {
  5925. if (research.tags.includes('arpa')) {
  5926. arpas[research.id].incPriority();
  5927. } else {
  5928. researches[research.id].incPriority();
  5929. }
  5930.  
  5931. let count = $('#'+research.id+'-prio')[0];
  5932. count.removeChild(count.firstChild);
  5933. if (research.tags.includes('arpa')) {
  5934. count.appendChild(document.createTextNode(arpas[research.id].priority));
  5935. } else {
  5936. count.appendChild(document.createTextNode(researches[research.id].priority));
  5937. }
  5938. });
  5939. let temp = (research.tags.includes('arpa')) ? arpas[research.id].priority : researches[research.id].priority;
  5940. let prioLabel = $('<span class="count current" id="'+research.id+'-prio" style="padding-right:5px;padding-left:5px;vertical-align:bottom;width:2rem;">'+temp+'</span>');
  5941. let prioControls = $('<div class="controls ea-research-tab" style="width:20%;text-align:center;">').append(prioSub).append(prioLabel).append(prioAdd).append('</div>');
  5942. researchDiv.append(prioControls);
  5943. }
  5944.  
  5945. // Set focus back on search
  5946. search.focus();
  5947. }
  5948.  
  5949. function createArpaToggle(name){
  5950. let arpaDiv = $('#arpa'+name +' .head');
  5951. let toggle = $('<label tabindex="0" class="switch ea-arpa-toggle" style="position:relative; max-width:75px;margin-top: -36px;left:45%;float:left;"><input type="checkbox" value=false> <span class="check" style="height:5px;"></span></label>');
  5952. arpaDiv.append(toggle);
  5953. if(settings.arpa[name]){
  5954. toggle.click();
  5955. toggle.children('input').attr('value', true);
  5956. }
  5957. toggle.on('mouseup', function(e){
  5958. let input = e.currentTarget.children[0];
  5959. let state = !(input.getAttribute('value') === "true");
  5960. input.setAttribute('value', state);
  5961. settings.arpa[name] = state;
  5962. updateSettings();
  5963. });
  5964. }
  5965. function createArpaToggles(){
  5966. removeArpaToggles();
  5967. createArpaToggle('lhc');
  5968. createArpaToggle('stock_exchange');
  5969. createArpaToggle('monument');
  5970. createArpaToggle('launch_facility');
  5971. }
  5972. function removeArpaToggles(){
  5973. $('.ea-arpa-toggle').remove();
  5974. }
  5975.  
  5976. function createAutoLog() {
  5977. let autolog = $('<div id="autolog" class="msgQueue right resource alt ea-autolog" style="display:none;"></div>');
  5978. $('#queueColumn').append(autolog);
  5979. }
  5980.  
  5981. /***
  5982. *
  5983. * Utilities
  5984. *
  5985. ***/
  5986.  
  5987. function messageQueue(msg,color){
  5988. color = color || 'warning';
  5989. var new_message = $('<p class="has-text-'+color+'">'+msg+'</p>');
  5990. $('#autolog').prepend(new_message);
  5991. if ($('#autolog').children().length > 30){
  5992. $('#autolog').children().last().remove();
  5993. }
  5994. }
  5995.  
  5996. function getTotalGameDays() {
  5997. try {
  5998. let str = $('#statsPanel')[0].children[$('#statsPanel')[0].children.length-1].innerText;
  5999. let reg = /Game Days Played: ([\d]+)/.exec(str);
  6000. return parseInt(reg[1]);
  6001. } catch(e) {
  6002. console.log('Error in getting total game days');
  6003. return null;
  6004. }
  6005. }
  6006. function getYear() {
  6007. try {
  6008. return parseInt($('.year > .has-text-warning')[0].innerText);
  6009. } catch(e) {
  6010. console.log('Error in getting current year');
  6011. return null;
  6012. }
  6013. }
  6014. function getDay() {
  6015. try {
  6016. return parseInt($('.day > .has-text-warning')[0].innerText);
  6017. } catch(e) {
  6018. console.log('Error in getting current day');
  6019. return null;
  6020. }
  6021. }
  6022. function getLunarPhase() {
  6023. try {
  6024. return $('.calendar > .is-primary')[0].attributes['data-label'].value;
  6025. } catch(e) {
  6026. console.log('Error in getting current lunar phase');
  6027. return null;
  6028. }
  6029. }
  6030. function getRace() {
  6031. try {
  6032. return $('#race > .column > span')[0].innerText;
  6033. } catch(e) {
  6034. console.log('Error in getting current race');
  6035. return null;
  6036. }
  6037. }
  6038.  
  6039. function getRealValue(num){
  6040. var suffix = {
  6041. K:1000,
  6042. M:1000000
  6043. }
  6044. var currSuff = /([-]?)([\.0-9]+)([^\d\.])/.exec(num);
  6045. if(currSuff !== null && currSuff.length == 4){
  6046. var sign = (currSuff[1] == "-") ? -1 : 1;
  6047. var n = parseFloat(currSuff[2]);
  6048. var suff = currSuff[3];
  6049. if (suffix[suff] !== null) {n *= suffix[suff];}
  6050. n *= sign;
  6051. return n;
  6052. }
  6053. return parseFloat(num);
  6054. }
  6055.  
  6056. function researched(id) {
  6057. let researched = $('#oldTech > div');
  6058. for (let i = 0;i < researched.length;i++) {
  6059. if (id == researched[i].id) {
  6060. return true;
  6061. }
  6062. }
  6063. return false;
  6064. }
  6065.  
  6066. function getMinMoney() {
  6067. if (settings.minimumMoney < 1) {
  6068. return settings.minimumMoney * resources.Money.storage;
  6069. } else {
  6070. return settings.minimumMoney;
  6071. }
  6072. }
  6073.  
  6074. function wouldBreakMoneyFloor(buyValue){
  6075. return resources.Money.amount - buyValue < getMinMoney();
  6076. }
  6077. })($);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement