Supremacy Ressource Helper

Can calculate various important statistics for the browsergame Supremacy 1914.

  1. // ==UserScript==
  2. // @name Supremacy Ressource Helper
  3. // @version 0.1
  4. // @description Can calculate various important statistics for the browsergame Supremacy 1914.
  5. // @match http://www.supremacy1914.de/play.php?L=1&gameID=*
  6. // @copyright 2014, Zahlii
  7. // @namespace https://greasyfork.org/users/6229
  8. // ==/UserScript==
  9.  
  10. function addGlobalStyle(css) {
  11. var head, style;
  12. head = document.getElementsByTagName('head')[0];
  13. if (!head) { return; }
  14. style = document.createElement('style');
  15. style.type = 'text/css';
  16. style.innerHTML = css;
  17. head.appendChild(style);
  18. }
  19.  
  20. function clone(item) {
  21. if (!item) { return item; } // null, undefined values check
  22.  
  23. var types = [ Number, String, Boolean ],
  24. result;
  25.  
  26. // normalizing primitives if someone did new String('aaa'), or new Number('444');
  27. types.forEach(function(type) {
  28. if (item instanceof type) {
  29. result = type( item );
  30. }
  31. });
  32.  
  33. if (typeof result == "undefined") {
  34. if (Object.prototype.toString.call( item ) === "[object Array]") {
  35. result = [];
  36. item.forEach(function(child, index, array) {
  37. result[index] = clone( child );
  38. });
  39. } else if (typeof item == "object") {
  40. // testing that this is DOM
  41. if (item.nodeType && typeof item.cloneNode == "function") {
  42. var result = item.cloneNode( true );
  43. } else if (!item.prototype) { // check that this is a literal
  44. if (item instanceof Date) {
  45. result = new Date(item);
  46. } else {
  47. // it is an object literal
  48. result = {};
  49. for (var i in item) {
  50. result[i] = clone( item[i] );
  51. }
  52. }
  53. } else {
  54. // depending what you would like here,
  55. // just keep the reference, or create new object
  56. if (false && item.constructor) {
  57. // would not advice to do that, reason? Read below
  58. result = new item.constructor();
  59. } else {
  60. result = item;
  61. }
  62. }
  63. } else {
  64. result = item;
  65. }
  66. }
  67.  
  68. return result;
  69. }
  70.  
  71. addGlobalStyle('td, th { text-align:center; }');
  72.  
  73. function handleGameSite() {
  74. var GAME_ID = location.href.match(/gameID=(\d+)/)[1];
  75.  
  76.  
  77. function ArmyCalculator() {
  78. var mainDiv;
  79. var mainDocument;
  80. var mapContainer;
  81. var ressourceContainer;
  82. var newspaperContainer;
  83. var diplomacyTable;
  84. var diplomacyContainer;
  85. var provinceContainer;
  86.  
  87. var _this = this;
  88.  
  89. var hideOverriddenContainer = function() {
  90. newspaperContainer.style.display = 'none';
  91. newspaperContainer.style.zIndex = '-1000';
  92. ressourceContainer.style.display = 'block';
  93. diplomacyContainer.style.display = 'none';
  94. };
  95.  
  96. this.init = function(main, cont) {
  97. mainDiv = main;
  98. mainDocument = cont;
  99. mapContainer = mainDocument.getElementById('mapContainer');
  100. ressourceContainer = mainDocument.getElementById('resource_bar');
  101. newspaperContainer = mainDocument.getElementById('newspaperContainer');
  102. diplomacyContainer = mainDocument.getElementById('diplomacyContainer');
  103. provinceContainer = mainDocument.getElementById('provinceListContainer');
  104.  
  105. window.setTimeout(function() {
  106. //mainDocument.getElementById('func_btn_diplomacy').click();
  107.  
  108. //diplomacyTable = mainDocument.getElementById('func_diplomacy_table');
  109. //_this.getDiplomacyData();
  110. }, 1000);
  111. _this.Ressources = new Ressources();
  112. _this.Provinces = new Provinces();
  113. };
  114. /*
  115. var data = [{
  116. num:30,
  117. moral:89
  118. },{
  119. num:80,
  120. moral:76
  121. },{
  122. num:70,
  123. moral:89
  124. }];
  125. function calcValForPlayer(x) {
  126. var res = data[x].num * (16 * data[x].moral/100 - 4);
  127. console.log(x,res);
  128. return res;
  129. }
  130. function calcForPlayer(x) {
  131. var sum = 0;
  132. for(var i=0,l=data.length;i<l;i++) {
  133. sum += calcValForPlayer(i);
  134. }
  135. console.log(sum);
  136. return calcValForPlayer(x)/sum*2000;
  137. }
  138. alert(calcForPlayer(2));
  139. */
  140.  
  141. var diplomacyData = [];
  142.  
  143. this.getDiplomacyData = function() {
  144. var r = diplomacyTable.getElementsByClassName('func_player_row');
  145. var detail;
  146.  
  147. var i = 0;
  148.  
  149. function handleNext() {
  150. if (i >= r.length) {
  151. handleStop();
  152. return;
  153. }
  154.  
  155. var td = r[i].getElementsByTagName('td');
  156. i++;
  157. td[10].getElementsByClassName('info_button')[0].click();
  158.  
  159. window.setTimeout(function() {
  160.  
  161. detail = mainDocument.getElementById('playerDetailContainer');
  162.  
  163. var ent = detail.getElementsByClassName('detail_entry');
  164.  
  165. var ind = ent.length > 6 ? 5 : 3;
  166. diplomacyData.push({
  167. playerCountryFlag: td[0].getElementsByTagName('img')[0].src,
  168. playerCountryName: td[1].textContent,
  169. playerName: td[3].textContent,
  170. playerProvinceCount: parseInt(td[4].textContent, 10),
  171. playerPowerIndex: parseInt(td[6].textContent),
  172. playerIsKI: (td[7].innerHTML.match(/inactive/) ? true : false),
  173. playerAvgMoral: parseFloat(ent[ind].getElementsByClassName('sg_float_l')[0].textContent.replace(/%/, ''))
  174. });
  175.  
  176. handleNext();
  177. }, 200);
  178. }
  179.  
  180. function handleStop() {
  181. window.setTimeout(function() {
  182. console.log(diplomacyData);
  183. detail.getElementsByClassName('close_button')[0].click();
  184. diplomacyContainer.getElementsByClassName('close_button')[0].click();
  185. }, 100);
  186. }
  187.  
  188. handleNext();
  189. };
  190.  
  191. var stringFill = function(x, n) {
  192. var s = '';
  193. for (;;) {
  194. if (n & 1)
  195. s += x;
  196. n >>= 1;
  197. if (n)
  198. x += x;
  199. else
  200. break;
  201. }
  202. return s;
  203. };
  204.  
  205. var pad = function(n, l, p) {
  206. if (l == null)
  207. l = 2;
  208. if (p == null)
  209. p = '0';
  210. n = '' + n;
  211.  
  212. return stringFill(p, l - n.length) + n;
  213. };
  214.  
  215. var formatInterval = function(time) {
  216. if (time < 0)
  217. return '-';
  218.  
  219. if(time == Number.POSITIVE_INFINITY)
  220. return '&infin;';
  221. var days = Math.floor(time / (24 * 3600 * 1000));
  222. time -= days * (24 * 3600 * 1000);
  223.  
  224. var hours = Math.floor(time / (3600 * 1000));
  225. time -= hours * (3600 * 1000);
  226.  
  227. var minutes = Math.floor(time / (60 * 1000));
  228. time -= minutes * (60 * 1000);
  229.  
  230. var seconds = Math.floor(time / 1000);
  231.  
  232. var dayS = (days > 1 ? days + ' Tage, ' : (days > 0 ? '1 Tag, ' : ''));
  233. var hoursS = hours > 0 ? pad(hours) + 'h ' : '';
  234. var minS = minutes > 0 ? pad(minutes) + 'm ' : '';
  235. var secS = pad(seconds) + 's';
  236.  
  237. return dayS + hoursS + minS + secS;
  238. }
  239.  
  240. var formatTime = function(date) {
  241. if (date == null)
  242. date = new Date();
  243. return pad(date.getDate()) + '.' + pad(date.getMonth() + 1) + '.' + date.getFullYear() + ' ' + pad(date.getHours()) + ':' + pad(date.getMinutes()) + ':' + pad(date.getSeconds());
  244. };
  245.  
  246. var formatNumber = function(n) {
  247. return number_format(n, 0, ',', '.');
  248. };
  249.  
  250. var getTime = function(dateStr) {
  251. var parts = dateStr.split(/[\.\s:]/);
  252. return new Date(parts[2], parts[1] == 0 ? 11 : parts[1] - 1, parts[0], parts[3], parts[4], parts[5]);
  253. };
  254.  
  255.  
  256.  
  257.  
  258. this.displayOverriddenContainer = function(title, content) {
  259. var html = ' <div class="main_popup_container">' +
  260. ' <div class="dialog_background_layer_80" id="func_modal_dialog"></div>' +
  261. ' <div class="metal_panel metal_dialog_header popup_shadow">' +
  262. ' <div class="metal_dialog_header_deco">' +
  263. ' <div class="deco-Scharnier"></div>' +
  264. ' </div>' +
  265. ' <div class="wooden_panel">' +
  266. ' <h1 class="capitals autoResizeLine">' + title + '</h1>' +
  267. ' </div>' +
  268. ' <div class="metal_dialog_close_area">' +
  269. ' <div class="close_button metal_dialog_close_button func_close_button">' +
  270. ' </div>' +
  271. ' </div>' +
  272. ' </div>' +
  273. ' <div class="metal_panel metal_dialog_body popup_shadow_bottom">' +
  274. ' <div class="wooden_panel">' +
  275. ' <div class="wooden_panel_content">' +
  276. ' <div class="paper_panel">' +
  277. ' <div class="paper_panel_content func_dialog_content">' +
  278. content +
  279. ' </div>' +
  280. ' </div>' +
  281. ' </div>' +
  282. ' </div>' +
  283. ' </div>' +
  284. ' </div>';
  285. ressourceContainer.style.display = 'none';
  286. newspaperContainer.style.display = 'block';
  287. newspaperContainer.innerHTML = html;
  288. newspaperContainer.style.zIndex = 1005;
  289. window.setTimeout(function() {
  290. newspaperContainer.getElementsByClassName('metal_dialog_close_area')[0].addEventListener('click', hideOverriddenContainer);
  291. }, 100);
  292. };
  293.  
  294. // type IN 'date', 'interval', 'number'
  295. this.format = function(n, type, symbol) {
  296. var symbol = symbol === null ? '' : symbol;
  297. switch (type) {
  298. case 'date':
  299. return formatTime(n);
  300. case 'interval':
  301. return formatInterval(n);
  302. case 'number':
  303. return formatNumber(n) + symbol;
  304. }
  305. }
  306.  
  307. function Provinces() {
  308. var self = this;
  309. var provinces;
  310. var sumInfo;
  311. var table;
  312.  
  313. var extract = function() {
  314. provinces = [];
  315. var tr = table.getElementsByTagName('tr');
  316.  
  317. var slots = 0;
  318.  
  319. for (var i = 0, l = tr.length; i < l; i++) {
  320. var t = tr[i];
  321. var td = t.getElementsByTagName('td');
  322.  
  323. var res = td[0].innerHTML.match(/icons-resource_(\d+)(_double)?/);
  324.  
  325. var buildings = td[2].getElementsByClassName('prov_list_building_slot');
  326.  
  327. var bName = ['Festung', 'Hafen', 'Eisenbahn', 'Wehramt', 'Kaserne', 'Fabrik'];
  328.  
  329. var bInfo = {};
  330. for (var j = 0, k = buildings.length; j < k; j++) {
  331. var b = buildings[j];
  332. if (b.innerHTML == '&nbsp;') {
  333. bInfo[bName[j]] = {
  334. buildingType: bName[j],
  335. buildingLevel: 0,
  336. buildingIsActive: false,
  337. buildingProgress: 0
  338. };
  339. } else {
  340. var level = b.getElementsByClassName('upgrade_level')[0] ? parseInt(b.getElementsByClassName('upgrade_level')[0].textContent, 10) : 1;
  341. var progress = b.innerHTML.match(/condition_(\d+)/) ? parseInt(b.innerHTML.match(/condition_(\d+)/)[1], 10) : 100;
  342. bInfo[bName[j]] = {
  343. buildingType: bName[j],
  344. buildingLevel: level,
  345. buildingIsActive: level > 1 || progress == 100,
  346. buildingProgress: progress
  347. };
  348. }
  349. }
  350.  
  351.  
  352. var data = {
  353. provinceID: parseInt(t.getAttribute('province_id'), 10),
  354. provinceRessourceID: parseInt(res[1], 10),
  355. provinceIsDouble: (res[2] == '_double'),
  356. provinceName: td[1].textContent.trim(),
  357. provinceIsCapital: (td[1].innerHTML.match(/non_capital/) ? false : true),
  358. provinceBuildings: bInfo,
  359. provinceIsBuilding: td[3].innerHTML.match(/icons-infoicon_building/) ? false : true,
  360. provinceIsProducing: td[4].innerHTML.match(/icons-infoicon_production/) ? false : true,
  361. };
  362.  
  363. var prod = data.provinceIsDouble ? 3136 * 2 : 3136;
  364. var tax = data.provinceIsDouble ? 2598 * 2 : 2598;
  365.  
  366. var inc_prod = prod;
  367. if (data.provinceBuildings.Hafen.buildingActive) {
  368. inc_prod += 0.25 * prod;
  369. }
  370. if (data.provinceBuildings.Eisenbahn.buildingActive) {
  371. inc_prod += 0.33 * prod;
  372. }
  373. data.provinceMaxProduction = Math.floor(inc_prod, 0);
  374. data.provinceMaxTax = tax;
  375. data.provinceMightProduce = data.provinceBuildings.Fabrik.buildingIsActive && !data.provinceIsProducing;
  376.  
  377. if (data.provinceMightProduce)
  378. slots++;
  379.  
  380. provinces.push(data);
  381.  
  382. }
  383.  
  384. var mapping = {
  385. 0:'Nahrung',
  386. 1:'Nahrung',
  387. 2:'Baumaterial',
  388. 3:'Baumaterial',
  389. 4:'Energie',
  390. 5:'Energie',
  391. 6:'Energie',
  392. 20:'Geld'
  393. };
  394.  
  395. var totalConsume = {
  396. 'Geld': 0,
  397. 'Nahrung': 0,
  398. 'Baumaterial': 0,
  399. 'Energie': 0
  400. }, baseConsume = {
  401. 'Geld': 0,
  402. 'Nahrung': 0,
  403. 'Baumaterial': 0,
  404. 'Energie': 0
  405. }, totalProduce = {
  406. 'Geld': 0,
  407. 'Nahrung': 0,
  408. 'Baumaterial': 0,
  409. 'Energie': 0
  410. }, totalResult = {
  411. 'Geld': {},
  412. 'Nahrung': {},
  413. 'Baumaterial': {},
  414. 'Energie': {}
  415. };
  416.  
  417.  
  418. for (var y = 0, o = provinces.length; y < o; y++) {
  419. var d = provinces[y];
  420.  
  421. var id = d.provinceRessourceID;
  422. var am = d.provinceMaxProduction;
  423.  
  424. totalProduce[mapping[id]] += am;
  425. totalProduce['Geld'] += d.provinceMaxTax;
  426. totalConsume['Geld'] += 250;
  427. totalConsume['Nahrung'] += 800;
  428. totalConsume['Baumaterial'] += 800;
  429. totalConsume['Energie'] += 800;
  430. /*baseConsume['Geld'] += 250;
  431. baseConsume['Nahrung'] += 800;
  432. baseConsume['Baumaterial'] += 800;
  433. baseConsume['Energie'] += 800;*/
  434.  
  435. if (d.provinceBuildings.Kaserne.buildingIsActive) {
  436. totalConsume['Nahrung'] += 1000 * d.provinceBuildings.Kaserne.buildingLevel;
  437. totalConsume['Geld'] += 500 * d.provinceBuildings.Kaserne.buildingLevel;
  438. }
  439. if (d.provinceBuildings.Eisenbahn.buildingIsActive) {
  440. totalConsume['Energie'] += 500;
  441. }
  442. }
  443.  
  444. var k = ['Geld','Nahrung','Baumaterial','Energie'];
  445. for(var i=0,l=k.length;i<l;i++) {
  446. var ck = k[i];
  447. var dif = totalProduce[ck] - totalConsume[ck];
  448. totalResult[ck] = {
  449. amountPerDay:dif,
  450. amountPerHour:Math.round(dif/24,2)
  451. };
  452. }
  453.  
  454. console.log(totalResult);
  455. sumInfo = {
  456. provinceCount: tr.length,
  457. freeProducingSlots: slots
  458. };
  459. };
  460.  
  461. var init = function() {
  462. table = mainDocument.getElementById('province_table');
  463. extract();
  464. }
  465. init();
  466. };
  467.  
  468.  
  469. function Ressources() {
  470. var self = this;
  471.  
  472. var ressources = [];
  473.  
  474.  
  475. var buildingQueue = [];
  476. this.addBuildingToQueue = function(type) {
  477. buildingQueue.push({
  478. buildingType: type,
  479. buildingPosition: buildingQueue.length,
  480. buildingRequirements: neededMap[type],
  481. buildingInfo:{}
  482. });
  483. self.recalculateQueue();
  484. };
  485. this.removeFromBuildingQueue = function(index) {
  486. if(index < 0 || index >= buildingQueue.length)
  487. return;
  488. buildingQueue.splice(index,1);
  489. self.recalculateQueue();
  490. };
  491. this.recalculateQueue = function() {
  492.  
  493. var currentRes = clone(ressources);
  494.  
  495. for(var i=0,l=buildingQueue.length;i<l;i++) {
  496. var e = buildingQueue[i];
  497. var n = e.buildingRequirements;
  498.  
  499. var t = self.getTimeNeededForRessource(n, currentRes);
  500. for(var prop in n) {
  501. if(!n.hasOwnProperty(prop))
  502. continue;
  503. prop = parseInt(prop,10);
  504. self.getRessourceById(prop, currentRes).ressourceAmount -= n[prop];
  505. }
  506. buildingQueue[i].buildingInfo = t;
  507. }
  508.  
  509. }
  510. var ressourceIdMap = {
  511. 20: 'Geld',
  512. 0: 'Getreide',
  513. 1: 'Fisch',
  514. 2: 'Eisenerz',
  515. 3: 'Holz',
  516. 4: 'Kohle',
  517. 5: 'Öl',
  518. 6: 'Gas'
  519. };
  520. var lastChosenQueueItem = '';
  521. this.displayBuildingQueue = function() {
  522. var img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACV0lEQVQ4T4WTzW8SQRiH3wUsGNKFXRCwH5hqldoEq0TiB22RIuXixavXGtN40z/EkzFooiaePHlqpQlfbWlSlR6qoiJtNWnV8jml1MpSdl13sLM0gHGS3U1m3ueZ3+zMULDf7gMYhjznE+lEcmLiJxcj/Qe/T7Va38mLg4E3kYTzLgDCYxR+YXj42mi676yNRZm8EH0+42uWYNhzYzzImI3KteVPhdmpBRuWUBh2+S+nj5/uZ8lsxVxBiL2I+ia4v0meabX+0eueacbIKknNWjJdmA2/slHxc4Nfzjjtfc2Ri3kkxIJxX4dSVI/43VOMkZFhUvs28W6FeqzReK64L4QMhoZdTlJEgoJSAMPqW+Ai2uKj4YWx+j+oS5yOEMs0FYoiiLU9gBoPoiAA/JYeqa9Y3uGjHz57J3l+vi4gErfdHmJpWinWagAcB+KeBEvAwYZ2d/nw6urYbYC4vAuyRKXyDHdZQ6zqUEtkXIO4ijD3Y917C2COMHIC3PEEwO8y9UzrOzTtBVVOiOe/tRc8BBgfMfe81P0DJjMiSbKYa0jqCQIAPpe5N0j/ByaSUrUivN6XUI8ArjrN1hla3Rp7WyrEkE59uGVJeGwpu+Glgp36lROsqb/5IJWrFX4ps+FVSMfdYemN0G0kaZRNUfcAWDtjSnXrmCNEUuYq/HJm3TsJMI/7HgC4HRZrhNY0knwvoWyylB+QL9Mp1pyy6BjjDveLf7/ZgIkUS4aOHot0SpLNbZT9iHIDdwBK8jbiS9VN6xez5dJNMnPzsrCki2YCX8tblzCMx/8AF+H3pjKo/BIAAAAASUVORK5CYII=';
  523. function getIcons() {
  524. var s = '';
  525. for(var prop in ressourceIdMap) {
  526. if(!ressourceIdMap.hasOwnProperty(prop))
  527. continue;
  528.  
  529. s += '<th>' + self.getRessourceById(parseInt(prop,10)).ressourceIcon +'</th>';
  530. }
  531. return s;
  532. }
  533. function getQueue() {
  534. var s = '';
  535. for(var i=0,l=buildingQueue.length;i<l;i++) {
  536. var b = buildingQueue[i];
  537. s += '<tr><td>' + (i+1) +'</td><td>' + b.buildingType +'</td>';
  538. for(var prop in ressourceIdMap) {
  539. if(!ressourceIdMap.hasOwnProperty(prop))
  540. continue;
  541. var t = typeof b.buildingRequirements[prop];
  542. var a = t !== 'undefined' ? _this.format(b.buildingRequirements[prop],'number',self.getRessourceById(parseInt(prop,10)).ressourceSymbol) : '-';
  543. s += '<td>' + a + '</td>';
  544. }
  545. var cls = b.buildingInfo.isPossible ? 'resource_bar_rate_positive' : 'resource_bar_rate_negative';
  546. s += '<td class="'+cls+'">' + b.buildingInfo.possibleFromString +'</td><td class="'+cls+'">' + b.buildingInfo.possibleUntilString +'</td>';
  547. s += '<td><img class="remove_building_queue" id="remove-' + i +'" src="'+img+'" style="cursor:pointer;" alt="X" /></td>';
  548. }
  549. return s +'</tr>';
  550. };
  551. var tbl = '<table class="full" id="building-queue" style="width:800px"><thead><tr><th>#</th><th>Typ</th>' + getIcons() + '<th>Möglich ab</th><th>Möglich bis</th><th>&nbsp;</th></tr></thead><tbody>'+getQueue()+'</tbody></table>';
  552. var sel = '<select id="select_projects">';
  553. for(var prop in neededMap) {
  554. if(!neededMap.hasOwnProperty(prop))
  555. continue;
  556. var issel = lastChosenQueueItem == prop ? 'selected="selected"' : '';
  557. sel += '<option value="'+prop+'" '+issel+'>'+prop+'</option>';
  558. }
  559. sel += '</select><div id="input_queue_submit" class="default_button">Einreihen</div>';
  560. _this.displayOverriddenContainer('Bauwarteschlange','<h2>Folgende Projekte sind eingereiht</h2>'+tbl+sel);
  561. window.setTimeout(function() {
  562. var sub = mainDocument.getElementById('input_queue_submit');
  563. sub.addEventListener('click',function() {
  564. var v = mainDocument.getElementById('select_projects').value;
  565. lastChosenQueueItem = v;
  566. self.addBuildingToQueue(v);
  567. self.displayBuildingQueue();
  568. });
  569. var t = mainDocument.getElementsByClassName('remove_building_queue');
  570. for(var i=0, l=t.length;i<l;i++) {
  571. var x = t[i];
  572. x.addEventListener('click', function(event) {
  573. var e = event.target || event.srcElement;
  574. var index = parseInt(e.id.split('-')[1],10);
  575. self.removeFromBuildingQueue(index);
  576. self.displayBuildingQueue();
  577. });
  578. }
  579. },100);
  580. }
  581.  
  582. var neededMap = {
  583. 'Wehramt': {
  584. 20: 1000,
  585. 2: 250,
  586. 3: 250
  587. },
  588. 'Werkstatt': {
  589. 20: 1000,
  590. 2: 500,
  591. 3: 500,
  592. 5: 500
  593. },
  594. 'Kaserne': {
  595. 20: 4000,
  596. 0: 1500,
  597. 3: 1500
  598. },
  599. 'Festung': {
  600. 20: 4000,
  601. 2: 2000
  602. },
  603. 'Hafen': {
  604. 20: 10000,
  605. 3: 10000
  606. },
  607. 'Eisenbahn': {
  608. 20: 10000,
  609. 3: 5000,
  610. 2: 3000,
  611. 4: 1000
  612. },
  613. 'Fabrik': {
  614. 20: 10000,
  615. 2: 2500,
  616. 3: 2500,
  617. 5: 2500
  618. },
  619. 'Panzerwagen': {
  620. 20: 7000,
  621. 2: 2000,
  622. 5: 1500
  623. },
  624. 'Artillerie': {
  625. 20: 10000,
  626. 2: 3000,
  627. 5: 2000
  628. },
  629. 'Panzer': {
  630. 20: 20000,
  631. 2: 5000,
  632. 5: 3000
  633. },
  634. 'EBG': {
  635. 20: 50000,
  636. 2: 10000,
  637. 3: 5000,
  638. 4: 5000,
  639. 5: 10000
  640. },
  641. 'Schlachtschiff': {
  642. 20: 50000,
  643. 2: 15000,
  644. 3: 5000,
  645. 4: 10000,
  646. 5: 5000
  647. }
  648. };
  649. var lastInput = {};
  650.  
  651. var extract = function() {
  652. ressources = [];
  653. var li = ressourceContainer.getElementsByTagName('li');
  654. for (var i = 0, l = li.length; i < l; i++) {
  655. var liE = li[i];
  656.  
  657. var amnt = liE.getElementsByClassName('resource_bar_amount')[0];
  658. if (typeof amnt === 'undefined')
  659. continue;
  660. var entry = amnt.parentNode;
  661.  
  662.  
  663.  
  664. var rate = entry.getElementsByTagName('div')[1];
  665. var resID = parseInt(liE.getAttribute('resource_id'));
  666.  
  667. amnt = parseInt(amnt.textContent.replace(/\./, ''), 10);
  668. rate = parseInt(rate.textContent.replace(/\./, '').replace(/\s\/h/, ''), 10);
  669.  
  670. var time = (rate >= 0 ? -1 : amnt / Math.abs(rate) * 3600 * 1000);
  671.  
  672. ressources.push({
  673. ressourceName: ressourceIdMap[resID],
  674. ressourceBarEntry: entry,
  675. ressourceID: resID,
  676. ressourceAmount: amnt,
  677. ressourceRate: rate,
  678. ressourceTimeLeft: time,
  679. ressourceTimeLeftText: _this.format(time, 'interval'),
  680. ressourceSymbol: resID === 20 ? '£' : 't',
  681. ressourceIcon: '<div class="icons-resource_' + resID + ' resource_bar_icon"></div>'
  682. });
  683. }
  684. }
  685. this.getRessourceInfo = function() {
  686. return ressources;
  687. }
  688. this.getRessourceById = function(id, res) {
  689. res = res == null ? ressources : res;
  690. for (var i = 0, l = res.length; i < l; i++) {
  691.  
  692. if (res[i].ressourceID === id)
  693. return res[i];
  694. }
  695. }
  696. this.getRessourceByName = function(name, res) {
  697. res = res == null ? ressources : res;
  698. for (var i = 0, l = res.length; i < l; i++) {
  699. if (res[i].ressourceName === name)
  700. return res[i];
  701. }
  702. }
  703. this.updateTimeLeftDisplay = function() {
  704. for (var i = 0, l = ressources.length; i < l; i++) {
  705. var res = ressources[i];
  706. if (mainDocument.getElementById('time_left_for_' + res.ressourceID) == null) {
  707. res.ressourceBarEntry.innerHTML += '<div id="time_left_for_' + res.ressourceID + '"></div>';
  708. }
  709.  
  710. var timeLeft = mainDocument.getElementById('time_left_for_' + res.ressourceID);
  711. timeLeft.className = res.ressourceTimeLeft > 0 ? 'resource_bar_rate_negative' : 'resource_bar_rate_positive';
  712. timeLeft.innerHTML = res.ressourceTimeLeftText;
  713. }
  714. };
  715.  
  716. this.getTimeNeededForRessource = function(need, base) {
  717. var mintime = Number.NEGATIVE_INFINITY; // from when to
  718. var maxtime = Number.POSITIVE_INFINITY; // when can it be built
  719. var isPossible = true;
  720. for (var prop in need) {
  721. if (!need.hasOwnProperty(prop))
  722. continue;
  723. var r = self.getRessourceById(parseInt(prop, 10), base);
  724. var dif = need[prop] - r.ressourceAmount;
  725. var time = dif / r.ressourceRate * 3600 * 1000;
  726. if (need[prop] <= 0) {
  727. continue;
  728. } else {
  729. if (dif < 0 && r.ressourceRate < 0) {// mehr da, nimmt aber ab
  730. if(time < maxtime)
  731. maxtime = time;
  732. }
  733. if (dif < 0 && r.ressourceRate > 0) {// mehr da, nimmt zu
  734. continue;
  735. }
  736. if (dif > 0 && r.ressourceRate < 0) {// weniger da, nimmt ab
  737. isPossible = false;
  738. break;
  739. }
  740. if (dif > 0 && r.ressourceRate > 0) {// weniger da, nimmt zu
  741. if(time > mintime)
  742. mintime = time;
  743. }
  744. }
  745. }
  746. mintime = Math.max(0,mintime);
  747. maxtime = Math.max(0,maxtime);
  748. return {
  749. isPossible:isPossible,
  750. possibleFrom:mintime,
  751. possibleFromString:_this.format(mintime +'','interval'),
  752. possibleUntil:Math.max(0,maxtime),
  753. possibleUntilString:_this.format(maxtime +'','interval'),
  754. };
  755. };
  756. var addTimeButton = function() {
  757. var ul = ressourceContainer.getElementsByTagName('ul')[0];
  758. if (mainDocument.body.innerHTML.indexOf('time_button"') === -1) {
  759. ul.innerHTML += '<li><input type="button" value="Ressourcen zu Zeitpunkt" id="time_button" class="default_button" /></li>';
  760. }
  761. window.setTimeout(function() {
  762. mainDocument.getElementById('time_button').addEventListener('click', function() {
  763. var dn = new Date();
  764. _this.displayOverriddenContainer('Ressourcen zu Zeitpunkt', '<h1>Bitte das Datum eingeben, für das Du die Ressourcen hochrechnen möchtest</h1>' + '<input type="text" value="' + formatTime() + '" id="input_date" /><div id="input_date_submit" class="default_button">Hochrechnen</div><br />' + '<table class="full" id="input_date_result" style="width:500px;">' + '<thead>' + '<tr><th>&nbsp;</th><th>Ressource</th><th>Vorrat</th><th>Veränderung</th></tr>' + '</thead>' + '<tbody>' + '</tbody>' + '</table>');
  765.  
  766. window.setTimeout(function() {
  767. mainDocument.getElementById('input_date_submit').addEventListener('click', function() {
  768. var d = mainDocument.getElementById('input_date').value;
  769. d = getTime(d);
  770.  
  771. var time_dif = d.getTime() - (new Date()).getTime();
  772.  
  773. var tbody = mainDocument.getElementById('input_date_result').getElementsByTagName('tbody')[0];
  774. tbody.innerHTML = '';
  775.  
  776. for (var i = 0, l = ressources.length; i < l; i++) {
  777. var r = ressources[i];
  778. var c = time_dif / (3600 * 1000) * r.ressourceRate;
  779. var a = r.ressourceAmount + c;
  780. var txt = _this.format(a, 'number', r.ressourceSymbol);
  781. var chng = _this.format(c, 'number', r.ressourceSymbol);
  782. var cls = c < 0 ? 'resource_bar_rate_negative' : 'resource_bar_rate_positive';
  783. var rowHtml = '<tr><td>' + r.ressourceIcon + '</td><td>' + r.ressourceName + '</td><td>' + txt + '</td><td><div class="' + cls + '">' + chng + '</div></td></tr>';
  784. tbody.innerHTML += rowHtml;
  785. }
  786. });
  787. }, 100);
  788. });
  789. }, 100);
  790. }
  791.  
  792. var addRessourceButton = function() {
  793. var ul = ressourceContainer.getElementsByTagName('ul')[0];
  794. if (mainDocument.body.innerHTML.indexOf('time_button_2"') === -1) {
  795. ul.innerHTML += '<li><input type="button" value="Zeit für Ressourcen" id="time_button_2" class="default_button" /></li>';
  796. }
  797. window.setTimeout(function() {
  798. mainDocument.getElementById('time_button_2').addEventListener('click', function() {
  799. var selStr = '<table style="width:500px;" id="input_projects"><thead><tr><th>Projekt</th><th>Anzahl</th></tr></thead><tbody>';
  800. for (var prop in neededMap) {
  801. if (!neededMap.hasOwnProperty(prop))
  802. continue;
  803.  
  804. selStr += '<tr><td>' + prop + '</td><td><input type="number" style="width:50px;" name="amount_' + prop + '" size="3" value="'+(lastInput[prop] ? lastInput[prop] : 0) +'" min="0" class="project"/></td></tr>';
  805. }
  806. selStr += '</tbody></table>';
  807. _this.displayOverriddenContainer('Zeit für Ressourcen', '<h1>Wähle aus folgenden Bauprojekten:</h1>' + selStr +
  808. '<br /><div id="input_date_submit_2" class="default_button">Zeitbedarf berechnen</div><br />' + '<table class="full" id="result_total_need" style="width:500px;">' + '<thead>' + '<tr><th>&nbsp;</th><th>Ressource</th><th>Insgesamt Benötigt</th><th>Zeit verbleibend</th></tr>' + '</thead>' + '<tbody>' + '</tbody>' + '</table>');
  809.  
  810. window.setTimeout(function() {
  811. mainDocument.getElementById('input_date_submit_2').addEventListener('click', function() {
  812. var el = mainDocument.getElementById('input_projects').getElementsByClassName('project');
  813. var need = {};
  814. for (var i = 0, l = el.length; i < l; i++) {
  815. var descr = el[i].name.split('_')[1];
  816. var n = neededMap[descr];
  817. var am = parseInt(el[i].value, 10);
  818. lastInput[descr] = am;
  819. if (!n)
  820. alert(n);
  821.  
  822. for (var prop in n) {
  823. if (!n.hasOwnProperty(prop))
  824. continue;
  825.  
  826. if (!need[prop])
  827. need[prop] = 0;
  828.  
  829. need[prop] += am * n[prop];
  830. }
  831. }
  832. var tbody = mainDocument.getElementById('result_total_need').getElementsByTagName('tbody')[0];
  833. tbody.innerHTML = '';
  834. for (var prop in need) {
  835. if (!need.hasOwnProperty(prop))
  836. continue;
  837.  
  838.  
  839. var r = self.getRessourceById(parseInt(prop, 10));
  840. var dif = need[prop] - r.ressourceAmount;
  841. var time = dif / r.ressourceRate * 3600 * 1000;
  842. var str = '', cls = '';
  843.  
  844. if (need[prop] <= 0) {
  845. str = 'Nicht benötigt.';
  846. cls = 'resource_bar_rate_positive';
  847. } else {
  848. if (dif < 0 && r.ressourceRate < 0) {// mehr da, nimmt aber ab
  849. str = 'Möglich bis in ' + _this.format(time, 'interval') + '.';
  850. cls = 'resource_bar_rate_positive';
  851. }
  852.  
  853. if (dif < 0 && r.ressourceRate > 0) {// mehr da, nimmt zu
  854. str = 'Vorhanden.';
  855. cls = 'resource_bar_rate_positive';
  856. }
  857.  
  858. if (dif > 0 && r.ressourceRate < 0) {// weniger da, nimmt ab
  859. str = 'Nicht möglich.';
  860. cls = 'resource_bar_rate_negative';
  861. }
  862.  
  863. if (dif > 0 && r.ressourceRate > 0) {// weniger da, nimmt zu
  864. str = 'Möglich ab ' + _this.format(time, 'interval') + '.';
  865. cls = 'resource_bar_rate_negative';
  866. }
  867.  
  868. }
  869. var rowHtml = '<tr><td>' + r.ressourceIcon + '</td><td>' + r.ressourceName + '</td><td>' + _this.format(need[prop], 'number', r.ressourceSymbol) + '</td><td><div class="'+cls+'">' + str + '</div></td></tr>';
  870. tbody.innerHTML += rowHtml;
  871. }
  872. });
  873. }, 100);
  874. });
  875. }, 100);
  876. }
  877.  
  878. var addQueueButton = function() {
  879. var ul = ressourceContainer.getElementsByTagName('ul')[0];
  880. if (mainDocument.body.innerHTML.indexOf('queue_button"') === -1) {
  881. ul.innerHTML += '<li><input type="button" class="default_button" value="Bauwarteschlange" id="queue_button" /></li>';
  882. }
  883. window.setTimeout(function() {
  884. mainDocument.getElementById('queue_button').addEventListener('click', function() {
  885. self.displayBuildingQueue();
  886. });
  887. });
  888. };
  889.  
  890. var init = function() {
  891. hideOverriddenContainer(); //nicer layout
  892. addTimeButton();
  893. addRessourceButton();
  894. addQueueButton();
  895. extract();
  896. self.updateTimeLeftDisplay();
  897.  
  898. };
  899. init();
  900. var run = function() {
  901. extract();
  902. self.updateTimeLeftDisplay();
  903. };
  904. window.setInterval(run, 2000);
  905. }
  906.  
  907. };
  908.  
  909.  
  910. var intervalStart = window.setInterval(handle, 500);
  911.  
  912. function number_format(number, decimals, dec_point, thousands_sep) {
  913.  
  914. number = (number + '')
  915. .replace(/[^0-9+\-Ee.]/g, '');
  916. var n = !isFinite(+number) ? 0 : +number,
  917. prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
  918. sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
  919. dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
  920. s = '',
  921. toFixedFix = function(n, prec) {
  922. var k = Math.pow(10, prec);
  923. return '' + (Math.round(n * k) / k)
  924. .toFixed(prec);
  925. };
  926. // Fix for IE parseFloat(0.55).toFixed(0) = 0;
  927. s = (prec ? toFixedFix(n, prec) : '' + Math.round(n))
  928. .split('.');
  929. if (s[0].length > 3) {
  930. s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
  931. }
  932. if ((s[1] || '')
  933. .length < prec) {
  934. s[1] = s[1] || '';
  935. s[1] += new Array(prec - s[1].length + 1)
  936. .join('0');
  937. }
  938. return s.join(dec);
  939. }
  940.  
  941. function handle() {
  942. var ifm = document.getElementById('ifm');
  943.  
  944. if (ifm == null || typeof ifm === 'undefined' || ifm.contentWindow == null || ifm.contentWindow.document == null)
  945. return;
  946.  
  947. var contWind = ifm.contentWindow.document;
  948. var main = contWind.getElementById('s1914');
  949.  
  950. if (main == null || typeof main === 'undefined' || main.innerHTML == null)
  951. return;
  952.  
  953.  
  954.  
  955. if (~main.innerHTML.indexOf('Global')) {
  956. window.clearInterval(intervalStart);
  957. (new ArmyCalculator()).init(main, contWind);
  958. }
  959. }
  960. }
  961.  
  962.  
  963.  
  964. handleGameSite();