Advertisement
Guest User

Untitled

a guest
May 22nd, 2019
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.33 KB | None | 0 0
  1. // ==UserScript==
  2. // @name WatchtowerEnhancer
  3. // @description Let's you see when an attack reaches your tower radius
  4. // @author Warre
  5. // @version 1.0
  6. // @grant none
  7. // @include https://*.tribalwars.nl*screen=overview_villages*
  8. // @include https://*.tribalwars.nl*info_command*type=other*
  9. // ==/UserScript==
  10.  
  11. /********************************
  12. ** Translations **
  13. ********************************/
  14.  
  15. var Translation = (function() {
  16. var lang;
  17. var msg = {
  18. 'nl' : {
  19. saveInfo : 'Informatie opslaan',
  20. saveInfoTitle : 'De nodige informatie van jouw uitkijktorens zal opgeslagen worden. Oude informatie zal verwijderd worden.',
  21. lastSaved : 'Laatst opgeslagen',
  22. infoSaved : 'Informatie opgeslagen',
  23. never : 'nooit',
  24. deleteInfo : 'Informatie verwijderen',
  25. deleteInfoTitle : 'Verwijder alle eerdere opgeslagen informatie.',
  26. infoDeleted : 'Informatie verwijderd',
  27. noWatchtowersLoaded : 'Geen wachttoren informatie ingeladen',
  28. viewIn : 'Zichtbaar in',
  29. multipleTags : 'meerdere tags',
  30. noTag : 'geen tag'
  31. },
  32. 'int' : {
  33. // NOT SUPORTED YET
  34. }
  35. };
  36.  
  37. var get = function() {
  38. lang = (msg.hasOwnProperty(game_data.market)) ? game_data.market : 'int';
  39.  
  40. return msg[lang];
  41. }
  42.  
  43. return {
  44. get : get
  45. }
  46. })();
  47.  
  48. /********************************
  49. ** WatchtowerEnhancer Code **
  50. ********************************/
  51.  
  52. var WatchtowerEnhancer = (function() {
  53. var general = (function () {
  54. var getRadius = function(lvl) {
  55. var lvlRadius = {
  56. '1' : 1.1,
  57. '2' : 1.3,
  58. '3' : 1.5,
  59. '4' : 1.7,
  60. '5' : 2,
  61. '6' : 2.3,
  62. '7' : 2.6,
  63. '8' : 3,
  64. '9' : 3.4,
  65. '10' : 3.9,
  66. '11' : 4.4,
  67. '12' : 5.1,
  68. '13' : 5.8,
  69. '14' : 6.7,
  70. '15' : 7.6,
  71. '16' : 8.7,
  72. '17' : 10,
  73. '18' : 11.5,
  74. '19' : 13.1,
  75. '20' : 15
  76. };
  77.  
  78. return lvlRadius[lvl];
  79. };
  80.  
  81. var getTags = function() {
  82. var tags = { // naam eenheid (afhankelijk van tagger) : looptijd van eenheid / veld (afhankelijk van wereld)
  83. 'Speer' : 18,
  84. 'speer' : 18,
  85. 'SP' : 18,
  86. 'sp' : 18,
  87.  
  88. 'Zwaard' : 22,
  89. 'zwaard' : 22,
  90. 'zw' : 22,
  91. 'zw' : 22,
  92.  
  93. 'Bijl' : 18,
  94. 'bijl' : 18,
  95.  
  96. 'Boogschutter' : 18,
  97. 'boogschutter' : 18,
  98. 'Boog' : 18,
  99. 'boog' : 18,
  100. 'BO' : 18,
  101. 'bo' : 18,
  102.  
  103.  
  104. 'Verk' : 9,
  105. 'verk' : 9,
  106. 'Scout' : 9,
  107. 'scout' : 9,
  108.  
  109. 'LCav' : 10,
  110. 'lcav' : 10,
  111. 'LC' : 10,
  112. 'lc' : 10,
  113.  
  114. 'BBoog' : 10,
  115. 'bboog' : 10,
  116. 'BB' : 10,
  117. 'bb' : 10,
  118.  
  119. 'ZCav' : 11,
  120. 'zcav' : 11,
  121. 'ZC' : 11,
  122. 'zc' : 11,
  123.  
  124. 'Ram' : 30,
  125. 'ram' : 30,
  126.  
  127. 'Kata' : 30,
  128. 'Kata' : 30,
  129.  
  130. 'Ridder' : 10,
  131. 'Edel' : 35
  132. }
  133.  
  134. return tags;
  135. };
  136.  
  137. return {
  138. getRadius : getRadius,
  139. getTags : getTags
  140. }
  141. })();
  142.  
  143. var storage = (function() {
  144. var id = game_data.player.id;
  145. var timestamp = $('#serverDate').text() + ' ' + $('#serverTime').text();
  146. var watchtowers = JSON.parse(localStorage.getItem('WatchtowerEnhancer_watchtowers_' + id));
  147.  
  148. var getWatchtowers = function(reset) {
  149. if (watchtowers === null || reset) {
  150. watchtowers = {
  151. 'date' : Translation.get().never,
  152. 'info' : {}
  153. }
  154.  
  155. localStorage.setItem('WatchtowerEnhancer_watchtowers_' + id, JSON.stringify(watchtowers));
  156.  
  157. if (reset) UI.SuccessMessage(Translation.get().infoDeleted);
  158. }
  159.  
  160. return watchtowers;
  161. };
  162.  
  163. var setWatchtowers = function(info) {
  164. watchtowers = {
  165. 'date' : timestamp,
  166. 'info' : info
  167. }
  168.  
  169. localStorage.setItem('WatchtowerEnhancer_watchtowers_' + id, JSON.stringify(watchtowers));
  170. UI.SuccessMessage(Translation.get().infoSaved);
  171. };
  172.  
  173. return {
  174. getWatchtowers : getWatchtowers,
  175. setWatchtowers : setWatchtowers
  176. }
  177. })();
  178.  
  179. var groupPage = (function() {
  180. var addInterface = function() {
  181.  
  182. var table = '<table class="vis WatchtowerEnhancer" style="width:100%;height: 34px;"><tr><th style="width: 10%;padding: 0px 8px;">WatchtowerEnhancer:</th><th>'
  183. + '<input type="button" class="btn tooltip uploadWatchtowers" style="margin-left:15px;" value="' + Translation.get().saveInfo + '">'
  184. + '<input type="button" class="btn tooltip deleteWatchtowers" style="margin-left:15px;" value="' + Translation.get().deleteInfo + '" title="' + Translation.get().deleteInfoTitle + '">'
  185. + '</th></tr></table>'
  186.  
  187. $('#buildings_table').before(table);
  188. groupPage.setUploadTitle();
  189. WatchtowerEnhancer.bindEventHandlers();
  190. groupPage.bindEventHandlers();
  191. };
  192.  
  193. var setUploadTitle = function() {
  194. $('.uploadWatchtowers').addClass('tooltip').attr('title', Translation.get().saveInfoTitle + '<br><br>' + Translation.get().lastSaved + ': ' + storage.getWatchtowers().date);
  195. WatchtowerEnhancer.bindEventHandlers();
  196. }
  197.  
  198. var bindEventHandlers = function() {
  199. $('.uploadWatchtowers').off('click').on('click', function() {
  200. var watchtowers = {};
  201. $('#buildings_table').find('td.b_watchtower').map(function() {
  202. if ($(this).find('.hidden').length == 0) {
  203. var coord = $(this).closest('tr').find('.quickedit-label').text().match(/\d{1,3}\|\d{1,3}/g).slice(-1)[0].toString();
  204. var radius = general.getRadius($(this).text().trim());
  205.  
  206. watchtowers[coord] = radius;
  207. }
  208. });
  209.  
  210. storage.setWatchtowers(watchtowers);
  211. groupPage.setUploadTitle();
  212. });
  213.  
  214. $('.deleteWatchtowers').off('click').on('click', function() {
  215. storage.getWatchtowers(true);
  216. groupPage.setUploadTitle();
  217. });
  218. };
  219.  
  220. return {
  221. addInterface : addInterface,
  222. setUploadTitle : setUploadTitle,
  223. bindEventHandlers : bindEventHandlers
  224. }
  225. })();
  226.  
  227. var incomingsPage = (function() {
  228. var addInterface = function() {
  229. var log = $('.server_info');
  230. if ($.isEmptyObject(storage.getWatchtowers().info)) {
  231. log.prepend('WacthtowerEnhancer -> ' + Translation.get().noWatchtowersLoaded + ' | ');
  232. } else {
  233. log.prepend('WacthtowerEnhancer -> ' + Translation.get().lastSaved + ': ' + storage.getWatchtowers().date + ' | ');
  234.  
  235. var $rows = $('#incomings_table').find('tr');
  236.  
  237. $rows.first().append('<th>' + Translation.get().viewIn + '</th>');
  238. $rows.not(':first, :last').append('<td class="WatchtowerEnhancer_result"></td>');
  239. $rows.last().find('th').last().attr('colspan', parseInt($rows.last().find('th').last().attr('colspan')) + 1);
  240.  
  241. for (var i = 1, l = $rows.length -1; i < l; i++) {
  242. var $this = $rows.eq(i);
  243.  
  244. if ($this.find('.quickedit-content').find('a').first().attr('href').match('type=other') && $this.find('.quickedit-content').find('img[src*="/command/attack.png"]').length > 0) {
  245. var home = $this.find('a[href*="screen=info_village"]').first().text().match(/\d{1,3}\|\d{1,3}/g).slice(-1)[0].toString();
  246. var target = $this.find('a[href*="screen=overview"]').first().text().match(/\d{1,3}\|\d{1,3}/g).slice(-1)[0].toString();
  247. var intersection = generalFunctions.getIntersections(home, target);
  248.  
  249. if (intersection) {
  250. var arival = generalFunctions.convertToTimestamp($this.find('td').eq(5).text().trim());
  251. var extract = generalFunctions.calculateDiff(intersection.distance, $this.find('.quickedit-label').text().trim());
  252.  
  253. if (typeof extract === 'string') {
  254. $this.find('.WatchtowerEnhancer_result').html(extract);
  255. } else {
  256. $this.find('.WatchtowerEnhancer_result').html('<span class="timer" data-endtime="' + (arival - extract) + '"></span>');
  257. }
  258. }
  259. }
  260. }
  261.  
  262. Timing.tickHandlers.timers.init(); // initiate timers
  263. }
  264. };
  265.  
  266. return {
  267. addInterface : addInterface
  268. }
  269. })();
  270.  
  271. var generalFunctions = (function(){
  272. var getIntersections = function(home, target) {
  273. function split(coord) {
  274. return coord.split('|');
  275. }
  276.  
  277. function TWdistance(targetC, originC) {
  278. targetC = targetC.split('|');
  279. originC = originC.split('|');
  280. return Math.sqrt(((originC[0]-targetC[0])*(originC[0]-targetC[0])+(originC[1]-targetC[1])*(originC[1]-targetC[1])));
  281. }
  282.  
  283. function distance(a,b) {
  284. return Math.sqrt( Math.pow(a[0]-b[0], 2) + Math.pow(a[1]-b[1], 2) )
  285. }
  286.  
  287. function is_on(a, b, c) {
  288. return distance(a,c) + distance(c,b) == distance(a,b);
  289. }
  290.  
  291. function calc(a, b, c) {
  292. // ORIGINAL CODE BY https://bl.ocks.org/milkbread/11000965#index.html
  293.  
  294. // Calculate the euclidean distance between a & b
  295. eDistAtoB = Math.sqrt( Math.pow(b[0]-a[0], 2) + Math.pow(b[1]-a[1], 2) );
  296.  
  297. // compute the direction vector d from a to b
  298. d = [ (b[0]-a[0])/eDistAtoB, (b[1]-a[1])/eDistAtoB ];
  299.  
  300. // Now the line equation is x = dx*t + ax, y = dy*t + ay with 0 <= t <= 1.
  301.  
  302. // compute the value t of the closest point to the circle center (cx, cy)
  303. t = (d[0] * (c[0]-a[0])) + (d[1] * (c[1]-a[1]));
  304.  
  305. // compute the coordinates of the point e on line and closest to c
  306. var e = {coords:[], onLine:false};
  307. e.coords[0] = (t * d[0]) + a[0];
  308. e.coords[1] = (t * d[1]) + a[1];
  309.  
  310. // Calculate the euclidean distance between c & e
  311. eDistCtoE = Math.sqrt( Math.pow(e.coords[0]-c[0], 2) + Math.pow(e.coords[1]-c[1], 2) );
  312.  
  313. // test if the line intersects the circle
  314. if( eDistCtoE < c[2] ) {
  315. // compute distance from t to circle intersection point
  316. dt = Math.sqrt( Math.pow(c[2], 2) - Math.pow(eDistCtoE, 2));
  317.  
  318. // compute first intersection point
  319. var f = {coords:[], onLine:false};
  320. f.coords[0] = ((t-dt) * d[0]) + a[0];
  321. f.coords[1] = ((t-dt) * d[1]) + a[1];
  322. // check if f lies on the line
  323. f.onLine = is_on(a,b,f.coords);
  324.  
  325. // compute second intersection point
  326. var g = {coords:[], onLine:false};
  327. g.coords[0] = ((t+dt) * d[0]) + a[0];
  328. g.coords[1] = ((t+dt) * d[1]) + a[1];
  329. // check if g lies on the line
  330. g.onLine = is_on(a,b,g.coords);
  331.  
  332. return {points: {intersection1:f, intersection2:g}, pointOnLine: e};
  333.  
  334. } else if (parseInt(eDistCtoE) === parseInt(c[2])) {
  335. //console.log("Only one intersection");
  336. return {points: false, pointOnLine: e};
  337. } else {
  338. //console.log("No intersection");
  339. return {points: false, pointOnLine: e};
  340. }
  341. }
  342.  
  343. var watchtowers = storage.getWatchtowers().info;
  344. var intersections = [];
  345.  
  346. for (var prop in watchtowers) {
  347. var a = [parseInt(split(home)[0]), parseInt(split(home)[1])];
  348. var b = [parseInt(split(target)[0]), parseInt(split(target)[1])];
  349. var c = [parseInt(split(prop)[0]), parseInt(split(prop)[1]), parseInt(watchtowers[prop])];
  350. var result = calc(a, b, c);
  351.  
  352. if (result.points) {
  353. for (var x in result.points) {
  354. if (result.points[x].onLine) {
  355. intersections.push(result.points[x].coords[0] + '|' + result.points[x].coords[1]);
  356. }
  357. }
  358. }
  359. }
  360.  
  361. if (intersections.length == 0) {
  362. return false;
  363. } else {
  364. var firstIntersection = {
  365. distance : 0,
  366. coord : ''
  367. };
  368.  
  369. for (var i = 0, l = intersections.length; i < l; i++) {
  370. var dis = TWdistance(target, intersections[i]);
  371.  
  372. if (dis > firstIntersection.distance) {
  373. firstIntersection.distance = dis;
  374. firstIntersection.coord = intersections[i];
  375. }
  376. }
  377.  
  378. return firstIntersection;
  379. }
  380. };
  381.  
  382. var convertToTimestamp = function(timestr) {
  383. // vandaag om 16:49:08 uur
  384. // op 21.08. om 05:04:11 uur
  385. var pos = timestr.indexOf(':');
  386. var T = timestr.substr(pos - 2, 8); //+','+MS;
  387.  
  388. var Serverdate = $('#serverDate').text().split('/');
  389. Serverdate = Serverdate[1] + ' ' + Serverdate[0] + ', ' + Serverdate[2];
  390. var Serverdate = new Date(Date.parse(Serverdate + ' ' + T));
  391.  
  392. if (timestr.match('vandaag')) {
  393. var D = Serverdate;
  394. } else if (timestr.match('morgen')) {
  395. var D = Serverdate;
  396. D.setDate(D.getDate() + 1);
  397. } else {
  398. var pos = timestr.indexOf('.');
  399. var d = timestr.substr(pos - 2, 5).split('.');
  400. d = d[1] + '/' + d[0] + '/' + Serverdate.getFullYear() + ' ' + T;
  401. var D = new Date(Date.parse(d));
  402. }
  403. return D.getTime()/1000;
  404. };
  405.  
  406. var calculateDiff = function(distance, tag) {
  407. var tags = general.getTags();
  408. var count = 0;
  409. var runtime = 0;
  410. for (var prop in tags) {
  411. if (tag.match(prop)) {
  412. runtime = tags[prop];
  413. count++;
  414. }
  415. }
  416.  
  417. if (count > 1) {
  418. return Translation.get().multipleTags;
  419. } else if (runtime == 0) {
  420. return Translation.get().noTag;
  421. } else {
  422. return (runtime * distance) * 60;
  423. }
  424. };
  425.  
  426. return {
  427. getIntersections : getIntersections,
  428. convertToTimestamp : convertToTimestamp,
  429. calculateDiff : calculateDiff
  430. }
  431. })();
  432.  
  433. var init = function() {
  434. switch (game_data.screen) {
  435. case 'overview_villages':
  436. if ($('#buildings_table').length > 0) groupPage.addInterface();
  437. if ($('#incomings_table').length > 0) incomingsPage.addInterface();
  438. break;
  439. }
  440. };
  441.  
  442. var bindEventHandlers = function() {
  443. UI.ToolTip($('.tooltip'));
  444. };
  445.  
  446. return {
  447. init : init,
  448. bindEventHandlers : bindEventHandlers
  449. }
  450. })();
  451.  
  452. $(function() {
  453. WatchtowerEnhancer.init();
  454. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement