Advertisement
Guest User

Untitled

a guest
Mar 30th, 2020
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.45 KB | None | 0 0
  1. :boom:
  2.  
  3. /* jshint freeze:false, bitwise:false, unused:false */
  4. /* global Game, GPWindowMgr, ngettext, Timestamp, DebugTranslations, GameData */
  5.  
  6. // TODO separate polyfills from common functions and native object extensions (should be undone if possible)
  7.  
  8. if (!Date.now) { // Emulate Date.now() for IE8
  9. Date.now = function() {
  10. return new Date().valueOf();
  11. };
  12. }
  13.  
  14. if (!String.prototype.camelCase) {
  15. String.prototype.camelCase = function() {
  16. return this.replace(/(?:\b|_)(.)/g, function (x, chr) {
  17. return chr.toUpperCase();
  18. });
  19. };
  20. }
  21.  
  22. if (!String.prototype.snakeCase) {
  23. String.prototype.snakeCase = function() {
  24. return this.replace(/([A-Z])/g, function(capital) {
  25. return '_' + capital.toLowerCase();
  26. }).replace(/^_/, '');
  27. };
  28. }
  29.  
  30. //inheritance wrapper
  31. if (!Function.prototype.inherits) {
  32. Function.prototype.inherits = function(F) {
  33. this.prototype = new F();
  34. this.prototype.constructor = this;
  35. this.prototype.parent = F.prototype;
  36. };
  37. }
  38.  
  39. if (!Number.prototype.between) {
  40. Number.prototype.between = function(a, b) {
  41. return (a < b ? this >= a && this <= b : this >= b && this <= a);
  42. };
  43. }
  44.  
  45. if (!Array.prototype.searchFor) {
  46. Array.prototype.searchFor = function(attr, value) {
  47. return this.filter(function(el) {
  48. return el[attr] == value; // jshint ignore:line
  49. });
  50. };
  51. }
  52.  
  53. if (!String.prototype.truncate) {
  54. String.prototype.truncate = function(limit) {
  55. var len = this.length;
  56.  
  57. return len > limit ? this.substr(0, limit) + '...' : this;
  58. };
  59. }
  60.  
  61. if (!Array.prototype.remove) {
  62. //Some array functions - By John Resig (MIT Licensed)
  63. Array.prototype.remove = function(from, to) {
  64. var rest = this.slice((to || from) + 1 || this.length);
  65. this.length = from < 0 ? this.length + from : from;
  66. return this.push.apply(this, rest);
  67. };
  68. }
  69.  
  70. if (!Array.prototype.max) {
  71. Array.prototype.max = function(array){
  72. return Math.max.apply(Math, array);
  73. };
  74. }
  75.  
  76. String.prototype.repeat = function (times) {
  77. 'use strict';
  78.  
  79. var out = '', i;
  80.  
  81. for (i = 0; i < times; i++) {
  82. out += this;
  83. }
  84.  
  85. return out;
  86. };
  87.  
  88. /**
  89. * us.min([1, 2]);
  90. *
  91. * @deprecated
  92. */
  93. if (!Array.prototype.min) {
  94. Array.prototype.min = function(array) {
  95. return Math.min.apply(Math, array );
  96. };
  97. }
  98.  
  99. if (!Array.prototype.clone) {
  100. Array.prototype.clone = function() {
  101. return this.slice(0);
  102. };
  103. }
  104.  
  105. /**
  106. * Strip HTML-Tags from a String
  107. */
  108. if (!String.prototype.strip) {
  109. String.prototype.strip = function () {
  110. return this.replace(/<(.|\n)*?>/g,'');
  111. };
  112. }
  113.  
  114. /**
  115. * Needed for IE10 because it doesn't support group function
  116. */
  117.  
  118. if (window.console && !window.console.group) {
  119. window.console.group = function(str) {
  120. return str;
  121. };
  122.  
  123. window.console.groupEnd = function() {
  124. return '';
  125. };
  126. }
  127.  
  128. /**
  129. * Checks if a string is lte than another string. If both strings start with a number, those values are parsed and then compared.
  130. *
  131. * @param y {String}
  132. */
  133.  
  134. if (!String.prototype.isLTE) {
  135. String.prototype.isLTE = function (y) {
  136. //parse
  137. var x = this,
  138. x_m = x.match(/^\s+\d+|^\d+/),
  139. y_m = y.match(/^\s+\d+|^\d+/),
  140. x_i = x_m !== null ? parseInt(x_m.shift(),10) : NaN,
  141. y_i = y_m !== null ? parseInt(y_m.shift(),10) : NaN;
  142. //compare strings if one isNaN
  143. if (isNaN(x_i) || isNaN(y_i)) {
  144. x = x.toLowerCase();
  145. y = y.toLowerCase();
  146. } else {
  147. x = x_i;
  148. y = y_i;
  149. }
  150. //compare
  151. return x <= y;
  152. };
  153. }
  154.  
  155. /**
  156. * Returns the Date as a short string
  157. */
  158. if (!Date.prototype.toShortString) {
  159. Date.prototype.toShortString = function(){
  160. var h, m, d, mn;
  161. h = ( ( h = this.getUTCHours()) < 10 ? '0' + h : h );
  162. m = ( ( m = this.getUTCMinutes()) < 10 ? '0' + m : m );
  163. d = ( ( d = this.getUTCDate()) < 10 ? '0' + d : d );
  164. mn = ( ( mn = this.getUTCMonth()+1) < 10 ? '0' + mn : mn );
  165. return ( h + ':' + m + ' ' + d + '/' + mn + '/' + this.getUTCFullYear());
  166. };
  167. }
  168.  
  169. function utf8Encode(string) {
  170. string = string.replace(/\r\n/g, '\n');
  171. var utftext = '',
  172. n;
  173.  
  174. for (n = 0; n < string.length; n++) {
  175.  
  176. var c = string.charCodeAt(n);
  177.  
  178. if (c < 128) {
  179. utftext += String.fromCharCode(c);
  180. }
  181. else if((c > 127) && (c < 2048)) {
  182. utftext += String.fromCharCode((c >> 6) | 192);
  183. utftext += String.fromCharCode((c & 63) | 128);
  184. }
  185. else {
  186. utftext += String.fromCharCode((c >> 12) | 224);
  187. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  188. utftext += String.fromCharCode((c & 63) | 128);
  189. }
  190.  
  191. }
  192.  
  193. return utftext;
  194. }
  195.  
  196. //private method for UTF-8 decoding
  197. function utf8Decode(utftext) {
  198. var string = '';
  199. var i = 0,
  200. c, c3, c2;
  201. c = c3 = c2 = 0;
  202.  
  203. while ( i < utftext.length ) {
  204. c = utftext.charCodeAt(i);
  205.  
  206. if (c < 128) {
  207. string += String.fromCharCode(c);
  208. i++;
  209. } else if ((c > 191) && (c < 224)) {
  210. c2 = utftext.charCodeAt(i+1);
  211. string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  212. i += 2;
  213. } else {
  214. c2 = utftext.charCodeAt(i+1);
  215. c3 = utftext.charCodeAt(i+2);
  216. string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  217. i += 3;
  218. }
  219. }
  220.  
  221. return string;
  222. }
  223.  
  224. /**
  225. * base64 decode / encode
  226. *
  227. * Modern browser provide us with a btoa and atob function, but these do not support unicode
  228. * @see https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/btoa
  229. *
  230. * for browsers with native btoa, we use a unicode alternative from the MDN
  231. * else we mock with a custom function (that works with unicode as well)
  232. *
  233. * the original btoa and atob are provided via window.__btoa and __atob
  234. */
  235.  
  236. if (window.btoa && window.encodeURIComponent) {
  237. window.__btoa = window.btoa;
  238. window.btoa = function(str) {
  239. return window.__btoa(window.unescape(encodeURIComponent(str)));
  240. };
  241. } else {
  242. window.btoa = function(str) {
  243. var key_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
  244. output = '',
  245. chr1, chr2, chr3, enc1, enc2, enc3, enc4,
  246. i = 0;
  247.  
  248. str = utf8Encode(str);
  249.  
  250. while (i < str.length) {
  251.  
  252. chr1 = str.charCodeAt(i++);
  253. chr2 = str.charCodeAt(i++);
  254. chr3 = str.charCodeAt(i++);
  255.  
  256. enc1 = chr1 >> 2;
  257. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  258. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  259. enc4 = chr3 & 63;
  260.  
  261. if (isNaN(chr2)) {
  262. enc3 = enc4 = 64;
  263. } else if (isNaN(chr3)) {
  264. enc4 = 64;
  265. }
  266.  
  267. output +=
  268. key_str.charAt(enc1) + key_str.charAt(enc2) +
  269. key_str.charAt(enc3) + key_str.charAt(enc4);
  270.  
  271. }
  272.  
  273. return output;
  274. };
  275. }
  276.  
  277. if (window.atob && window.decodeURIComponent) {
  278. window.__atob = window.atob;
  279. window.atob = function(str) {
  280. return decodeURIComponent(window.escape(window.__atob(str)));
  281. };
  282. } else {
  283. window.atob = function(str) {
  284. var key_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
  285. output = '',
  286. i = 0,
  287. len = str.length;
  288.  
  289. var enc1, enc2, enc3, enc4;
  290.  
  291. var chr1, chr2, chr3;
  292.  
  293. str = str.replace(/[^A-Za-z0-9\+\/\=]/g, '');
  294.  
  295. while(i < len){
  296. enc1 = key_str.indexOf(str.charAt(i++));
  297. enc2 = key_str.indexOf(str.charAt(i++));
  298. enc3 = key_str.indexOf(str.charAt(i++));
  299. enc4 = key_str.indexOf(str.charAt(i++));
  300.  
  301. chr1 = (enc1 << 2) | (enc2 >> 4);
  302. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  303. chr3 = ((enc3 & 3) << 6) | enc4;
  304.  
  305. output += String.fromCharCode(chr1);
  306.  
  307. if (enc3 !== 64) {
  308. output = output + String.fromCharCode(chr2);
  309. }
  310. if (enc4 !== 64) {
  311. output = output + String.fromCharCode(chr3);
  312. }
  313. }
  314.  
  315. return utf8Decode(output);
  316. };
  317. }
  318.  
  319. window.cycle = function() {
  320. var toggle = false;
  321.  
  322. return function(a, b) {
  323. return (toggle = !toggle) ? a : b;
  324. };
  325. }();
  326.  
  327. /**
  328. * jQuery.blocker
  329. *
  330. * @param object options
  331. * @return {self}
  332. *
  333. * minimum example:
  334. * $.blocker({html: $('<div>This is an (visual) blocking note</div>')});
  335. */
  336. jQuery.blocker = function(options){
  337. var settings = jQuery.extend({
  338. id: '', // rename to caching
  339. caching: options.id,
  340. html: 'f00',
  341. width: 520,
  342. height: 200,
  343. gameloader: false,
  344. bgClickable: true,
  345. success: '',
  346. cssClass : '',
  347. onSuccess: function(){},
  348. cancel: '',
  349. onCancel: function(){},
  350. callback: void(0)
  351. }, options);
  352.  
  353. var block_wrapper = '<div class="gpwindow_frame ' + settings.cssClass + '" style="position: absolute; top: ' + (($(window).height() - settings.height) / 2) + 'px;' +
  354. 'left: ' + (($(window).width() - settings.width) / 2) + 'px; width: ' + settings.width + 'px; height: ' + settings.height + 'px; z-index: 5000; display: block;">' +
  355. '<div class="gpwindow_left"></div><div class="gpwindow_right"></div><div class="gpwindow_bottom"><div class="gpwindow_left corner"></div><div class="gpwindow_right corner">'+
  356. '</div></div><div class="gpwindow_top"><div class="gpwindow_left corner"></div><div class="gpwindow_right corner"></div></div>' +
  357. '<div class="gpwindow_content"></div>';
  358. var frame = $(block_wrapper);
  359.  
  360. var elm = {
  361. box: frame,
  362. bg: $('<div id="blockbox_bg"></div>'),
  363. body: $('body')
  364. };
  365.  
  366. elm.content = elm.box.find('div.gpwindow_content');
  367.  
  368. // show
  369. this.blocker.block = function(){
  370. //save location ... otherwise use document body
  371. var tmp = settings.html.parent();
  372. elm.original_parent = tmp.length ? tmp : $('body');
  373.  
  374. elm.html = settings.html.detach();
  375. elm.content.append(elm.html.show());
  376.  
  377. elm.box.appendTo(elm.body).show();
  378. elm.bg.appendTo(elm.body).show();
  379. };
  380.  
  381. this.blocker.handleEvents = function(){
  382. // set handlers
  383. if(settings.bgClickable){
  384. elm.bg.bind('click.block', function(){
  385. jQuery.blocker.unblock();
  386. });
  387. }
  388. // bind user defined functions to elements
  389. $(settings.success).unbind('click').click(function(){
  390. settings.onSuccess();
  391. jQuery.blocker.unblock();
  392. });
  393. $(settings.cancel).unbind('click').click(function(){
  394. settings.onCancel();
  395. jQuery.blocker.unblock();
  396. });
  397. };
  398.  
  399. this.blocker.unblock = function(){
  400. elm.box.hide().detach();
  401. elm.bg.hide().detach();
  402. if(settings.gameloader){
  403. elm.html.remove();
  404. } else {
  405. elm.html.appendTo(elm.original_parent).hide();
  406. }
  407. if(settings.callback && typeof settings.callback === 'function'){
  408. settings.callback();
  409. }
  410. };
  411.  
  412. this.blocker.block();
  413. this.blocker.handleEvents();
  414.  
  415. return this.blocker;
  416. };
  417.  
  418. /**
  419. * @param controller String
  420. * @param parameters Object
  421. */
  422. function buildLink(controller, parameters) {
  423. var params = [],
  424. key;
  425. for(key in parameters) {
  426. params.push(key + '=' + escape(parameters[key]));
  427. }
  428. // always append the CSRF token
  429. params.push('h=' + encodeURIComponent(Game.csrfToken));
  430.  
  431. return '/game/' + controller + '?' + params.join('&');
  432. }
  433. /**
  434. * Generates a link from the given parameters.
  435. *
  436. * @param controller String
  437. * @param action String
  438. * @param parameters Object
  439. * @return String
  440. */
  441. function url(controller, action, parameters) {
  442. if (controller && controller.substr(0, 1) === '/') {
  443. return controller;
  444. }
  445. controller = controller || Game.controller;
  446. parameters = parameters || {};
  447.  
  448. if (typeof action !== 'undefined' && action !== '') {
  449. parameters.action = action;
  450. }
  451. parameters.town_id = parameters.town_id || Game.townId;
  452.  
  453. return buildLink(controller, parameters);
  454. }
  455.  
  456. /**
  457. * Transforms seconds to hours:minutes:seconds
  458. * @param {number} duration in seconds
  459. * @param {boolean} only_non_zero - if true, omits any leading 0s
  460. * @return {String}
  461. */
  462. function day_hr_min_sec(duration, only_non_zero, options) {
  463. var result, days, hours, minutes, seconds, hours_str, minutes_str, seconds_str,
  464. lang = {
  465. days : __('day|d'),
  466. hours : __('hour|h'),
  467. minutes : __('minute|m'),
  468. seconds : __('second|s')
  469. };
  470.  
  471. function getSecondsHtml() {
  472. return with_seconds ? (seconds_str + '<span>' + lang.seconds+'</span>') : '';
  473. }
  474.  
  475. options = options || {};
  476. var with_seconds = typeof options.with_seconds === "undefined" ? true : options.with_seconds;
  477.  
  478. if (duration === 0) {
  479. return _('Now');
  480. }
  481.  
  482. days = parseInt(duration / 86400, 10);
  483. hours = parseInt((duration / 3600) % 24, 10);
  484. minutes = parseInt((duration / 60) % 60, 10);
  485. seconds = parseInt(duration % 60, 10);
  486.  
  487. //Days won't be displayed when == 0
  488. result = days > 0 ? days + '<span>' + lang.days + '</span>&nbsp;' : '';
  489.  
  490. //Add 0 at the beginning if number is smaller than 10
  491. hours_str = (hours < 10) ? '0' + hours : hours;
  492. minutes_str = (minutes < 10) ? '0' + minutes : minutes;
  493. seconds_str = (seconds < 10) ? '0' + seconds : seconds;
  494.  
  495. if (only_non_zero) {
  496. result += (hours > 0 || days > 0) ? (hours_str + '<span>' + lang.hours + '</span>&nbsp;') : '';
  497. result += (minutes > 0 || hours > 0 || days > 0) ? (minutes_str + '<span>' + lang.minutes + '</span>&nbsp;') : '';
  498. result += getSecondsHtml();
  499. } else {
  500. result += hours_str + '<span>' + lang.hours + '</span>&nbsp;' +
  501. minutes_str + '<span>' + lang.minutes + '</span>&nbsp;' +
  502. getSecondsHtml();
  503. }
  504.  
  505. return result;
  506. }
  507.  
  508. /**
  509. * Transforms seconds to x hours (y minutes) (z seconds)
  510. * primary used for inline texts e.g. in power effects
  511. *
  512. * @param {integer} duration
  513. * @see TimeFormat.php formatTime()
  514. * @return {string}
  515. */
  516. function hours_minutes_seconds(duration) {
  517. var weeks, days, hours, minutes, seconds,
  518. str = [];
  519.  
  520. weeks = Math.floor(duration / 604800);
  521. days = Math.floor((duration / 86400) % 7);
  522. hours = Math.floor((duration / 3600) % 24);
  523. minutes = Math.floor((duration / 60) % 60);
  524. seconds = Math.floor(duration % 60);
  525.  
  526. if (weeks > 0) {
  527. str.push(weeks + ' ' + ngettext('week', 'weeks', weeks));
  528. }
  529. if (days > 0) {
  530. str.push(days + ' ' + ngettext('day', 'days', days));
  531. }
  532. if (hours > 0) {
  533. str.push(hours + ' ' + ngettext('hour', 'hours', hours));
  534. }
  535. if (minutes > 0) {
  536. str.push(minutes + ' ' + ngettext('minute', 'minutes', minutes));
  537. }
  538. if (seconds > 0) {
  539. str.push(seconds + ' ' + ngettext('second', 'seconds', seconds));
  540. }
  541.  
  542. return str.join(' ');
  543. }
  544.  
  545. /**
  546. * Transforms date object to readable format
  547. *
  548. * @param object date
  549. * @param boolean date is utc
  550. * @param boolean ext_date - flag if a date with day and month should be returned
  551. * @param boolean with_seconds - flag if a date with seconds should be returned
  552. * @return String
  553. */
  554. function readableDate(date, utc, ext_date, with_seconds) {
  555. return readableUnixTimestamp(date.getTime(), (utc === true ? 'no_offset' : 'player_timezone'), {extended_date: ext_date, with_seconds: with_seconds});
  556. }
  557.  
  558. /**
  559. * Transforms a unix timestamp to readable format
  560. * This readable format could depend on a timezone:
  561. * - player_timezone := player timezone from his settings (default)
  562. * - lc_timezone := servers lc_timezone
  563. * - no_offset := no timezone offset
  564. *
  565. * The options object can hold of those two boolean flags
  566. * - extended_date := flag if a date with day and month should be returned
  567. * - with_seconds := flag if a date with seconds should be returned
  568. *
  569. * @param {integer} timestamp
  570. * @param {string} timezone_type
  571. * @param {object} options
  572. * @return String
  573. */
  574. function readableUnixTimestamp(timestamp, timezone_type, options) {
  575. options = options === undefined ? {} : options;
  576.  
  577. var with_seconds = options.with_seconds === undefined ? true : options.with_seconds;
  578. var extended_date = options.extended_date === undefined ? false : options.extended_date;
  579.  
  580. var ts = (timezone_type === 'no_offset' ? timestamp : Timestamp.shiftUnixTimestampByTimezoneOffset(timestamp, timezone_type));
  581.  
  582. var date = new Date(ts * 1E3);
  583. var hours, minutes, seconds, days, months;
  584. var result;
  585.  
  586. hours = date.getUTCHours();
  587. minutes = date.getUTCMinutes();
  588. seconds = date.getUTCSeconds();
  589.  
  590. if (minutes < 10) {
  591. minutes = '0' + minutes;
  592. }
  593.  
  594. if (seconds < 10) {
  595. seconds = '0' + seconds;
  596. }
  597.  
  598. if (extended_date) {
  599. days = date.getUTCDate();
  600. months = date.getUTCMonth() + 1;
  601.  
  602. if (days < 10) {
  603. days = '0' + days;
  604. }
  605.  
  606. if (months < 10) {
  607. months = '0' + months;
  608. }
  609.  
  610. result = days + '.' + months + '.|' + hours + ':' + minutes + (with_seconds ? (':' + seconds) : '');
  611. } else {
  612. result = hours + ':' + minutes + (with_seconds ? (':' + seconds) : '');
  613. }
  614.  
  615. return result;
  616. }
  617. /**
  618. * Returns a ratio string from a given float.
  619. * One side of the ratio is 1.
  620. * The other side is always >=1.
  621. * e.g.
  622. * 1.2 -> '1.2':1
  623. * 0.8 -> '1:1.2'
  624. *
  625. * @param {number} fraction
  626. * @return {string}
  627. */
  628. function readableRatio(fraction) {
  629. var bigger_part = Math.round( (fraction >= 1 ? fraction : (1/fraction)) * 100 ) / 100;
  630. if (fraction < 1) {
  631. return '1:' + bigger_part;
  632. } else {
  633. return bigger_part + ':1';
  634. }
  635. }
  636.  
  637. // Translation tool, return s
  638. // Strings wrapped with this will get translated
  639. function _(s) {
  640. if (DebugTranslations.isEnabled()) {
  641. return DebugTranslations.markString(s);
  642. }
  643.  
  644. return s;
  645. }
  646.  
  647. // Translation tool, return s
  648. // Strings wrapped with this will NOT get translated
  649. function _literal(s) {
  650. return s;
  651. }
  652.  
  653. // context aware gettext alias - only used for dev
  654. // and fallback in case of missing translation
  655. function __(s) {
  656. if (DebugTranslations.isEnabled()) {
  657. return DebugTranslations.markString(s.substr(s.indexOf('|')+1));
  658. }
  659.  
  660. return s.substr(s.indexOf('|')+1);
  661. }
  662.  
  663. function s(text) {
  664. var i;
  665. if(!text){
  666. return '';
  667. }
  668. for(i = 1; i<arguments.length; i++) {
  669. text = text.split('%'+i).join(arguments[i]);
  670. }
  671.  
  672. return text;
  673. }
  674.  
  675. /**
  676. * Debugging function.
  677. *
  678. * @param whatever Object
  679. */
  680. function debug(whatever){
  681. var i, s;
  682. if(!Game.dev) {
  683. return;
  684. }
  685. try {
  686. if(arguments.length > 1){
  687. console.group();
  688. for(i = 0; i < arguments.length; i++){
  689. console.debug(arguments[i]);
  690. }
  691. console.groupEnd();
  692. } else {
  693. console.log(whatever);
  694. }
  695. } catch(x){
  696. try {
  697. opera.postError(whatever);
  698. } catch(y){
  699. if ('object' === typeof(whatever)) {
  700. s = '';
  701. for (var i in whatever){
  702. s += i + ': ' + whatever[i] + '\n';
  703. }
  704. alert(s);
  705. } else {
  706. alert(whatever);
  707. }
  708. }
  709. }
  710. }
  711.  
  712. jQuery.extend(jQuery.easing,{
  713. // t: current time, b: beginning value, c: change in value, d: duration
  714. bounce: function (x, t, b, c, d) {
  715. if ((t/=d) < (1/2.75)) {
  716. return c*(7.5625*t*t) + b;
  717. } else if (t < (2/2.75)) {
  718. return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
  719. } else if (t < (2.5/2.75)) {
  720. return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
  721. } else {
  722. return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
  723. }
  724. }
  725. });
  726.  
  727. /**
  728. * @deprecated, use .bind()/.click()/.whatever() instead.
  729. */
  730. function w(foo){
  731. var elm = foo || this;
  732. if (elm.wnd) {
  733. return elm.wnd;
  734. }
  735.  
  736. while (elm.parentNode &&
  737. // if element has a tagName different from 'DIV', we skip it. This is mainly a workaround
  738. // for <form>-elements, which cause serious problems when used with this function, e. g.:
  739. // an error is thrown with something like: form#[object HTMLInputElement]
  740. ((elm = elm.parentNode).tagName !== 'DIV' ? elm = elm.parentNode : elm).id.indexOf('gpwnd') === -1){
  741. null;
  742. }
  743.  
  744. var id = (~~elm.id.match(/\d+/));
  745. elm.wnd = GPWindowMgr.GetByID(id);
  746. return elm.wnd;
  747. }
  748.  
  749. function attr(attribs){
  750. var res = '',
  751. att;
  752.  
  753. for (att in attribs) {
  754. if (attribs[att]) {
  755. res = res + ' ' + att + '="' + attribs[att] + '"';
  756. }
  757. }
  758. return res;
  759. }
  760.  
  761. /**
  762. * function to create a button as string or jquery object
  763. *
  764. * @param string text
  765. * @param object html_options
  766. * @param boolean as_string (optional: default false)
  767. * @return object either string or jquery object
  768. */
  769. function button(text, html_options, as_string, wnd) {
  770. var btn,
  771. button_text,
  772. callback,
  773. css_class = 'button';
  774.  
  775. if (html_options.hasOwnProperty('class')) {
  776. css_class += ' ' + html_options['class'];
  777. }
  778.  
  779. if (!html_options.href) {
  780. html_options.href = '#';
  781. }
  782. if ((callback = html_options.onclick) && typeof callback === 'function') {
  783. // if we bind a function, we cannot return a string
  784. as_string = false;
  785. delete html_options.onclick;
  786. }
  787.  
  788. html_options = attr(html_options);
  789.  
  790. button_text = '<a class="' + css_class + '" ' + html_options + '>'+
  791. '<span class="left"><span class="right">'+
  792. '<span class="middle">' + text + '</span>'+
  793. '</span></span>'+
  794. '<span style="clear:both;"></span>' +
  795. '</a>';
  796.  
  797. if (!as_string) {
  798. btn = $(button_text);
  799. }
  800. // if callback insted of onclick:
  801. if (callback && !as_string) {
  802. btn.click(function() {
  803. callback.apply(wnd);
  804. });
  805. }
  806.  
  807. return as_string ? button_text : btn;
  808. }
  809.  
  810.  
  811. /**
  812. * checks if argument is a number
  813. *
  814. * @param object val
  815. * @return boolean
  816. */
  817. function isNumber(val){
  818. return typeof val === 'number' && isFinite(val);
  819. }
  820.  
  821. /**
  822. * checks if argument is an array
  823. *
  824. * @param {object} o
  825. * @return boolean
  826. */
  827. function is_array(o){
  828. return typeof o === 'object' && (o instanceof Array);
  829. }
  830.  
  831. /**
  832. * adds slashes to string
  833. *
  834. * @param str string
  835. * @return string
  836. */
  837. function addslashes(str) {
  838. var result = str || '';
  839. result = result.replace(/\\/g,'\\\\');
  840. result = result.replace(/\'/g,'\\\'');
  841. result = result.replace(/\"/g,'\\"');
  842. result = result.replace(/\0/g,'\\0');
  843. return result;
  844. }
  845.  
  846. /**
  847. * get human readable time and date format: hours:minutes:seconds day/month/year
  848. */
  849. function getHumanReadableTimeDate(time) {
  850. // http://www.hunlock.com/blogs/Javascript_Dates-The_Complete_Reference
  851. var hours = time.getUTCHours(),
  852. minutes = time.getUTCMinutes(),
  853. seconds = time.getUTCSeconds(),
  854. day = time.getUTCDate(),
  855. month = time.getUTCMonth() + 1,
  856. year = time.getUTCFullYear();
  857.  
  858. if (hours < 10) {
  859. hours = '0' + hours;
  860. }
  861. if (minutes < 10) {
  862. minutes = '0' + minutes;
  863. }
  864. if (seconds < 10) {
  865. seconds = '0' + seconds;
  866. }
  867. if (day < 10) {
  868. day = '0' + day;
  869. }
  870. if (month < 10) {
  871. month = '0' + month;
  872. }
  873. return hours + ':' + minutes + ':' + seconds + ' ' + day + '/' + month + '/' + year;
  874. }
  875.  
  876. /**
  877. * get human readable date format: day/month/year
  878. */
  879. function getHumanReadableDate(timestamp) {
  880. var day = timestamp.getUTCDate(),
  881. month = timestamp.getUTCMonth() + 1,
  882. year = timestamp.getUTCFullYear();
  883.  
  884. if (day < 10) {
  885. day = '0' + day;
  886. }
  887. if (month < 10) {
  888. month = '0' + month;
  889. }
  890. return day + '/' + month + '/' + year;
  891. }
  892.  
  893.  
  894. /**
  895. * creates a date object by the date arguments supplied. A concrete timezone
  896. * for the date supplied can be specified
  897. *
  898. * @param {integer} year
  899. * @param {integer} month
  900. * @param {integer} day
  901. * @param {integer} hours
  902. * @param {integer} minutes
  903. * @param {integer} seconds
  904. * @param {integer} timezone_offset (in seconds) GMT +02 = 7200
  905. *
  906. * @return object date
  907. */
  908. function newDateByTimezone(year, month, day, hours, minutes, seconds, timezone_offset){
  909. var date = new Date();
  910. date.setUTCFullYear(year, month, day);
  911. date.setUTCHours(hours, minutes, seconds - timezone_offset);
  912.  
  913. return date;
  914. }
  915.  
  916.  
  917. /**
  918. * Only used in wndhandler_attack and building_place
  919. * TODO: get rid of this method in common.js
  920. * @param units Array
  921. * @param data Object unit data for current town
  922. * @param pop jQuery element for display of selected population
  923. * @param cap jQuery element for display of total capacity
  924. * @param progbar jQuery progressbar element
  925. */
  926. function recalcCapacity(units, researches, pop, cap, progbar, slow_boats_needed, fast_boats_needed) {
  927. researches = researches || 0;
  928.  
  929. var q, progress,
  930. total_capacity = 0,
  931. total_population = 0,
  932. // TODO!
  933. pwidth = 460,
  934. berth = researches.berth || 0,
  935. gdunits = GameData.units,
  936. big_transporter_cap = gdunits.big_transporter.capacity,
  937. small_transporter_cap = gdunits.small_transporter.capacity;
  938.  
  939. units.each(function() {
  940. var i = this.name,
  941. count = ~~this.value,
  942. cap;
  943.  
  944. // don't do anything if 0 or a flying unit
  945. if (count && !gdunits[i].flying) {
  946. if (gdunits[i].is_naval) {
  947. // add research-modifiers if they exist
  948. total_capacity += ((cap = gdunits[i].capacity) + (cap ? researches.berth || 0 : 0)) * count;
  949. } else {
  950. total_population += gdunits[i].population * count;
  951. }
  952. }
  953. });
  954.  
  955. q = total_population / total_capacity;
  956. progress = ( q >= 1 || !total_capacity) ? 0 : (1 - q) * -pwidth;
  957.  
  958. pop.text(total_population);
  959. cap.text(total_capacity);
  960. progbar.stop(true,true).animate({backgroundPosition: progress + 'px'});
  961.  
  962. if (slow_boats_needed) {
  963. slow_boats_needed.text(Math.ceil(total_population / (big_transporter_cap + berth)));
  964. }
  965.  
  966. if (fast_boats_needed) {
  967. fast_boats_needed.text(Math.ceil(total_population / (small_transporter_cap + berth)));
  968. }
  969.  
  970. return {
  971. 'capacity': total_capacity,
  972. 'population': total_population
  973. };
  974. }
  975.  
  976. function isSomeThing(checks, anyOrAll) {
  977. var isSomeThing, uagent;
  978.  
  979. return function() {
  980. var check_idx, checks_length = checks.length, check;
  981.  
  982. if (typeof isSomeThing === 'boolean') {
  983. return isSomeThing;
  984. }
  985. else {
  986. uagent = navigator.userAgent.toLowerCase();
  987. if (anyOrAll === 'any') {
  988. for (check_idx = 0; check_idx < checks_length; ++check_idx) {
  989. check = checks[check_idx];
  990. isSomeThing = isSomeThing || uagent.indexOf(check) > -1;
  991. }
  992. } else {
  993. isSomeThing = true;
  994. for (check_idx = 0; check_idx < checks_length; ++check_idx) {
  995. check = checks[check_idx];
  996. isSomeThing = isSomeThing && uagent.indexOf(check) > -1;
  997. }
  998. }
  999.  
  1000. return isSomeThing;
  1001. }
  1002. };
  1003. }
  1004.  
  1005. var isiOs = isSomeThing(['iphone', 'ipad', 'ipod'], 'any');
  1006. var isIeTouch = isSomeThing(['touch', 'trident', 'tablet'], 'all');
  1007. var isMsApp = isSomeThing(['trident', 'msapphost'], 'all');
  1008.  
  1009. function isSmallScreen() {
  1010.  
  1011. if (isSmallScreen.result) {
  1012. return isSmallScreen.result;
  1013. }
  1014.  
  1015. if ($(window).height() <= 800) {
  1016. isSmallScreen.result = true;
  1017. } else {
  1018. isSmallScreen.result = false;
  1019. }
  1020.  
  1021. return isSmallScreen.result;
  1022. }
  1023.  
  1024. /**
  1025. * Generated a DWORD (32-bit-integer) from 2 WORDS (16 bit ints)
  1026. *
  1027. * @param {Number} lo Lower Half WORD
  1028. * @param {Number} hi Higher Half WORD
  1029. * @return {Number} generated DWORD
  1030. */
  1031. function makeDWord(lo, hi) {
  1032. return (lo & 0xffff ) | ((hi & 0xffff) << 16);
  1033. }
  1034.  
  1035. var Sort = {
  1036. sort_by: null,
  1037.  
  1038. /**
  1039. * Setter method for the values by which the list should be sorted
  1040. *
  1041. * @param {String} string classname of any sortable value
  1042. */
  1043. sortBy: function (string) {
  1044. this.sort_by = string;
  1045. },
  1046. /**
  1047. * checks if list is already sorted by a value
  1048. */
  1049. sortedBy: function(string) {
  1050. return this.sort_by === string;
  1051. },
  1052.  
  1053. /**
  1054. * Sorts an array via quicksort. sortBy() must be used first.
  1055. *
  1056. * @param {Array} array The array which has to be sorted
  1057. */
  1058. qsort: function(array) {
  1059. var greater = [], less = [];
  1060. if (!array || array.length <= 1) {
  1061. return array;
  1062. }
  1063. else {
  1064. var index = Math.floor(Math.random() * (array.length - 1));
  1065. var pivot = array[index], i;
  1066. array.splice(index,1);
  1067. for (i = 0; i < array.length; i++) {
  1068. var obj = array[i];
  1069. var x = $(obj).find('span.sortable.' + this.sort_by).text();
  1070. var y = $(pivot).find('span.sortable.' + this.sort_by).text();
  1071.  
  1072. if (x.isLTE(y)) {
  1073. less.push(obj);
  1074. }
  1075. else {
  1076. greater.push(obj);
  1077. }
  1078. }
  1079. return (this.qsort(less).concat(pivot)).concat(this.qsort(greater));
  1080. }
  1081. }
  1082. };
  1083.  
  1084. /**
  1085. * change digit to roman numerals (up to 4000)
  1086. */
  1087. function romanNumerals(val) {
  1088. var values = [1000, 900, 500, 400, 100,90, 50, 40, 10, 9, 5, 4, 1],
  1089. numerals = ['min', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'],
  1090. vl = values.length,
  1091. i = 0,
  1092. rest = val,
  1093. return_val = '';
  1094.  
  1095. for (; i < vl; ++i) {
  1096. while (rest > values[i]) {
  1097. rest -= values[i];
  1098. return_val += numerals[i];
  1099. }
  1100. }
  1101.  
  1102. return return_val;
  1103. }
  1104.  
  1105. if (!window.getComputedStyle) {
  1106. window.getIEComputedStyle = function(el, pseudo) {
  1107. this.el = el;
  1108. this.getPropertyValue = function(prop) {
  1109. var re = /(\-([a-z]){1})/g;
  1110. if (prop === 'float') {
  1111. prop = 'styleFloat';
  1112. }
  1113. if (re.test(prop)) {
  1114. prop = prop.replace(re, function () {
  1115. return arguments[2].toUpperCase();
  1116. });
  1117. }
  1118. return el.currentStyle[prop] ? el.currentStyle[prop] : null;
  1119. };
  1120. this.cssText = function() {
  1121. if(!el) {
  1122. return false;
  1123. }
  1124. var elStyle = el.currentStyle,
  1125. cssText = '';
  1126. for (var k in elStyle) { cssText += k + ':' + elStyle[k] + ';';}
  1127. return cssText.replace(/([A-Z])/g, function($1){return '-'+$1.toLowerCase();});
  1128. }();
  1129.  
  1130. return this;
  1131. };
  1132. }
  1133.  
  1134. function difference(template, override) {
  1135. var ret = {};
  1136. for (var name in template) {
  1137. if (template.hasOwnProperty(name) && name in override) {
  1138. if (us.isObject(override[name]) && !us.isArray(override[name])) {
  1139. var diff = difference(template[name], override[name]);
  1140. if (!us.isEmpty(diff)) {
  1141. ret[name] = diff;
  1142. }
  1143. } else if (!us.isEqual(template[name], override[name])) {
  1144. ret[name] = override[name];
  1145. }
  1146. }
  1147. }
  1148. return ret;
  1149. }
  1150.  
  1151. /**
  1152. * Shortens a string exceeding the total_max_length with an ellipsis (3 dots)
  1153. * total_max_length includes the length of the ellipsis!
  1154. *
  1155. * @param {String} string_to_shorten
  1156. * @param {number} total_max_length
  1157. */
  1158. function ellipsis(string_to_shorten, total_max_length) {
  1159. if (string_to_shorten.length <= total_max_length) {
  1160. return string_to_shorten;
  1161. }
  1162.  
  1163. return string_to_shorten.slice(0, total_max_length - 1) + '\u2026';
  1164. }
  1165. /**
  1166. * Wrapper for the native number.toLocaleString() in order to make sure the game locale is used.
  1167. * @param number
  1168. * @return {string|*}
  1169. */
  1170. function numberToLocaleString(number) {
  1171. var toLocaleStringSupportsLocales = function() {
  1172. var test_number = 0;
  1173. try {
  1174. test_number.toLocaleString('i');
  1175. } catch (e) {
  1176. return e.name === 'RangeError';
  1177. }
  1178. return false;
  1179. },
  1180. locale = Game.locale_lang.replace('_','-');
  1181.  
  1182. return toLocaleStringSupportsLocales() ?
  1183. number.toLocaleString(locale) :
  1184. number;
  1185. }
  1186.  
  1187. (function($) {
  1188. 'use strict';
  1189.  
  1190. /**
  1191. * When element is hidden with display:none; we can not get its proper size
  1192. * in this case, we have to show him for a while somewhere out of the viewport,
  1193. * take the size, and restore values
  1194. */
  1195. $.fn.hiddenOuterWidth = function(include_margin) {
  1196. include_margin = include_margin ? true : false;
  1197.  
  1198. var $el = $(this),
  1199. old_styles = {
  1200. left : $el.css('left'),
  1201. display : $el.css('display'),
  1202. position : $el.css('position'),
  1203. visibility : $el.css('visibility'),
  1204. width : $el.css('width')
  1205. }, outer_width;
  1206.  
  1207. $el.css({left : 300, display : 'block', position : 'absolute', visibility: 'visible'});
  1208.  
  1209. outer_width = $el.outerWidth(include_margin);
  1210.  
  1211. $el.css(old_styles);
  1212.  
  1213. return outer_width;
  1214. };
  1215.  
  1216. /**
  1217. *
  1218. */
  1219. $.fn.setOffsetWidth = function(value) {
  1220. var $el = $(this),
  1221. margins_width = $el.outerWidth(true) - $el.outerWidth();
  1222.  
  1223. $el.width(value - margins_width);
  1224.  
  1225. return this;
  1226. };
  1227. }(jQuery));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement