您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enhancements for the user interface of Ikariam.
当前为
- // ==UserScript==
- // @name Enhanced UI
- // @description Enhancements for the user interface of Ikariam.
- // @namespace Tobbe
- // @author Tobbe
- // @version 2.5
- //
- // @include http://s*.*.ikariam.*/*
- // @include http://s*.ikariam.gameforge.com/*
- //
- // @exclude http://support.*.ikariam.gameforge.com/*
- //
- // @resource languageGerman http://resources.ikascripts.de/74221/v2.3/languageGerman.json
- // @resource languageEnglish http://resources.ikascripts.de/74221/v2.3/languageEnglish.json
- // @resource languageLatvian http://resources.ikascripts.de/74221/v2.3/languageLatvian.json
- //
- // @grant unsafeWindow
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_deleteValue
- // @grant GM_listValues
- // @grant GM_getResourceText
- // @grant GM_xmlhttpRequest
- //
- // @history 2.5 Bugfix: Game language is recognized again.
- // @history 2.5 Bugfix: Works now in Greasemonkey 2.0+
- // @history 2.5 Checks now for updates on Greasy Fork.
- // @history 2.5 Removed code parts for mobile version.
- // @history 2.5 Removed alliance page improvement, as fixed in Ikariam v0.5.13
- //
- // @history 2.4 New Ikariam domain -> script can now be used with this domain
- //
- // @history 2.3 Feature: Formatting troop lists for posting in forums / personal messages. (desktop).
- // @history 2.3 Feature: Filling level of warehouse as bar in town view. (desktop).
- // @history 2.3 Feature: Link to mines / town hall when clicking on resources / citizens. (desktop).
- // @history 2.3 Feature: New versioning system.
- // @history 2.3 Bugfix: Some characters in links were not decoded correctly. (desktop)
- // @history 2.3 Bugfix: Watching a foreign city causes a abortion of the script. (desktop)
- // @history 2.3 Bugfix: The city dropdown sometimes was zoomed in world view. (desktop)
- // @history 2.3 Bugfix: Removed obsolete CSS styles for Firefox.
- // @history 2.3 Adjustments in the language files.
- // @history 2.3 Violent Monkey brings Greasemonkey functions to Opera.
- //
- // @history 2.2.1 Feature: Smaller icons in direct military tooltip. (desktop)
- // @history 2.2.1 Bugfix: Problems with update check and version numbers >= 10. (mobile & desktop)
- // @history 2.2.1 Bugfix: Problems with another script. (desktop)
- // @history 2.2.1 Bugfix: Problems with a wrong style in island view. (desktop)
- //
- // @history 2.2 Feature: Message signature can be set. (desktop)
- // @history 2.2 Feature: Button for faster sending of circular messages. (desktop)
- // @history 2.2 Feature: Make links in messages clickable. (desktop)
- // @history 2.2 Feature: Show town infos of colonizing cities. (desktop)
- // @history 2.2 Feature: Information about cargo / fleets is displayed directly in military view. (desktop)
- // @history 2.2 Feature: Script options: Sections on the script tab can be folded. (desktop)
- // @history 2.2 Bugfix: Tooltips with mouseover were not clickable anymore. (desktop)
- // @history 2.2 Changes in code for better overview.
- //
- // @history 2.1.1 Feature: Different styles for income in town view. (desktop)
- // @history 2.1.1 Feature: Remaining resources after upgrade. (desktop)
- // @history 2.1.1 Feature: Improved style for external alliance pages. (desktop)
- // @history 2.1.1 Feature: Refresh the missing / remaining resources in ruction view automatically. (desktop)
- //
- // @history 2.1 Feature: Show the missing resources in ruction view. (desktop)
- // @history 2.1 Feature: Show the hourly income directly in town view and add the daily production as popup. (desktop)
- // @history 2.1 Feature: Don't center town information in the town advisor. (desktop)
- // @history 2.1 Feature: Save the highscore data of alliance members and compare it with the actual value. (desktop)
- // @history 2.1 Bugfix: There was an error with a missing language package and seperators. (mobile & desktop)
- // @history 2.1 Bugfix: Some things in worldview were not resized correctly. (desktop)
- // @history 2.1 Prevent more than one script execution.
- // @history 2.1 Prevent more than one script option panel (the script option panel now is usable for other scripts, too).
- //
- // @history 2.0.1 Bugfix: Zooming was broken.
- // @history 2.0.1 Bugfix: Dropdown menus created by the script were broken.
- // @history 2.0.1 Bugfix: Tooltips in in Alliance / Military view were not shown correctly.
- //
- // @history 2.0 Feature: Cross-browser compatibility. (Firefox, Chrome, Opera)
- // @history 2.0 Feature: Latvian translation - thanks to Draxo. (mobile & desktop)
- // @history 2.0 Feature: Possibility to hide the update hint for a new script version. (mobile & desktop)
- // @history 2.0 Bugfix: Resizing the owner state in world view was broken. (desktop)
- // @history 2.0 Some changes in the code for easier copying of functions which should be used by more than one script.
- //
- // @history 1.7 Feature: Resizing banners when zooming is possible in city view, too. (desktop)
- // @history 1.7 Feature: The zoom buttons are available in world view, too. (desktop)
- // @history 1.7 Feature: Zooming with the mouse scroll is possible again (now with key, standard is ctrl). (desktop)
- // @history 1.7 Feature: Changes in the option panel due to the new zooming function features. (desktop)
- // @history 1.7 Bugfix: If resizing is enabled, zooming with the buttons will resize the banners, too. (desktop)
- // @history 1.7 Bugfix: The chat will not cause to much executions of script functions. (desktop)
- // @history 1.7 The language texts are integrated as resources, so that there is shorter code.
- // @history 1.7 Replace the GM_* functions by myGM.* to expand them easy and add new.
- //
- // @history 1.6 Feature: Possibility to hide only the bird swarm animation. (desktop)
- // @history 1.6 Feature: Easier upkeep reduction table. (mobile & desktop)
- // @history 1.6 Feature: Enhanced zoom function using the Ikariam zoom function. (desktop)
- // @history 1.6 Due to the use of Ikariam functions the code could be reduced.
- // @history 1.6 Code enhancements for shorter code.
- //
- // @history 1.5.1.1 Bugfix: Not all occurrences of hidden were changed.
- //
- // @history 1.5.1 Bugfix: Name of a class (hidden) is used by GF.
- //
- // @history 1.5 Feature: Options panel to enable/disable funtions and set settings. (mobile & desktop)
- // @history 1.5 Feature: Update interval can be set. (mobile & desktop)
- // @history 1.5 Feature: Manually check for updates. (mobile & desktop)
- // @history 1.5 Feature: Zoom funtion without resizing the whole view. (desktop)
- // @history 1.5 Feature: Move loading circle to another position. (desktop)
- // @history 1.5 Feature: Show tooltip in Alliance / Military view on mouseover. (desktop)
- // @history 1.5 Feature: Code better commented. More comments, so that it is easier to understand.
- // @history 1.5 Bugfix: Changed *.gif to *.png.
- // @history 1.5 Version numbers adjusted.
- //
- // @history 1.4.1 Feature: Support for mobile interface.
- // @history 1.4.1 Bugfix: Fixed bug with scrollbar in finances view. (desktop)
- //
- // @history 1.4 Feature: Ready for 0.5.0, but also supports 0.4.5 furthermore.
- // @history 1.4 Feature: Implemented support for different languages.
- // @history 1.4 Feature: Enhanced script updater.
- // @history 1.4 Feature: Cleaned up code.
- // @history 1.4 Feature: Rename the script to "Enhanced UI".
- // @history 1.4 Feature: Change the namespace to "Tobbe".
- // @history 1.4 Because of the change of namespace and name you have to delete the old script manually!
- //
- // @history 1.3.3 Bugfix: Problem with negative numbers and 0.4.2.4 fixed.
- //
- // @history 1.3.2 Feature: Own script updater.
- // @history 1.3.2 Bugfix: Remove everything what refered to other scripts.
- //
- // @history 1.3.1 Feature: New script updater.
- //
- // @history 1.3 Remove the script updater (Because of the problem with Greasemonkey scripts).
- //
- // @history 1.2.1 Feature: New style of update panel.
- // @history 1.2.1 Bugfix: Bug with ',' as seperator fixed.
- //
- // @history 1.2 Feature: Income in 24h added.
- // @history 1.2 Feature: Cleaned up code.
- //
- // @history 1.1 Feature: Update check implemented.
- //
- // @history 1.0 Initial release.
- // ==/UserScript==
- /******************************************************************************************************************
- *******************************************************************************************************************
- *** ***
- *** The update function which is used in the script was developed by PhasmaExMachina and adapted by me (Tobbe). ***
- *** ***
- *******************************************************************************************************************
- ******************************************************************************************************************/
- /**
- * Information about the Script.
- */
- var scriptInfo = {
- version: '2.5',
- id: 4369,
- name: 'Ikariam Enhanced UI',
- author: 'Tobbe',
- debug: false
- };
- /**
- * Information about the language.
- */
- var languageInfo = {
- implemented: new Array('English', 'German', 'Latvian'),
- useResource: true,
- defaultText: {"default":{"update":{"notPossible":{"header":"No Update possible","text1":"It is not possible to check for updates for ","text2":". Please check manually for Updates for the script. The actual installed version is ","text3":". This message will appear again in four weeks."},"possible":{"header":"Update available","text1":"There is an update for ","text2":" available.","text3":"At the moment there is version ","text4":" installed. The newest version is ","history":"Version History","type":{"feature":"Feature(s)","bugfix":"Bugfix(es)","other":""},"button":{"install":"Install","hide":"Hide"}},"noNewExists":{"header":"No Update available","text1":"There is no new version for ","text2":" available. The newest version ","text3":" is installed."}},"notification":{"header":"Script notification","button":{"confirm":"OK","abort":"Abort"}}},"settings":{"kiloSep":",","decSep":".","left2right":true},"general":{"successful":"Your order has been carried out.","error":"There was an error in your request.","ctrl":"Ctrl","alt":"Alt","shift":"Shift","yes":"Yes","no":"No","show":"Show","hide":"Hide"},"balance":{"income":{"perHour":"Income per hour","perDay":"Income per day","start":"Income without reduction"},"upkeep":{"reason":{"0":"Troops","1":"Ships","2":"Troops & Ships"},"basic":"Basic Costs","supply":"Supply Costs","result":"Total Costs"}},"optionPanel":{"scripts":"Scripts","save":"Save settings!","section":{"module":{"title":"Modules","label":{"updateActive":"Search for updates automatically","incomeOnTopActive":"Show income on top in Balance view","upkeepReductionActive":"Show a short version of the upkeep reduction","missingResActive":"Show missing resources in construction view","resourceInfoActive":"Show the hourly income directly in town view","capacityInfoActive":"Show info bar for warehouse capacity","easyAccessActive":"Link resource number to town hall / mines","zoomActive":"Activate zoom in world view, island view, town view","messageSignatureActive":"Enable message signatures","easyCircularMsgActive":"Show button for faster sending of circular messages","replaceUrlsActive":"Make links in messages clickable","colonizingLinksActive":"Show information about colonizing cities","lcMoveActive":"Move loading circle to position bar","tooltipsAutoActive":"Show tooltips in alliance mebers view and military advisor automatically","directMilitaryTtActive":"Show information about cargo / fleets in military view without tooltips","unitInfoActive":"Show troop info","hideBirdsActive":"Hide the bird swarm.","nctAdvisorActive":"Don't center town information in the town advisor","niceAllyPageActive":"Show the external allypages better formatted","memberInfoActive":"Enable the possibility to save highscore data of alliance members"}},"update":{"title":"Update","label":{"interval":{"description":"Interval to search for updates:","option":{"hour":"1 hour","hour12":"12 hours","day":"1 day","day3":"3 days","week":"1 week","week2":"2 weeks","week4":"4 weeks"}},"manual":{"text1":"Search for updates for ","text2":"!"}}},"resInfoMissingRes":{"title":"Resource Information / Missing Resources","label":{"hourlyIncomeStyle":"Style of the hourly income in town view:","align":{"right":"Right align","left":"Left align","rightWithSeparation":"Right align with separation"},"capacityOrientationStyle":"Orientation of the bar","orientation":{"vertical":"Vertical","horizontal":"Horizontal","horizontalFull":"Horizontal, full length"},"hasBorder":"Has border","showBranchRes":"Show resources in trading post","showPositive":"Show also the remaining resources after an upgrade","showColoured":"Show the remaining resources coloured"}},"zoom":{"title":"Zoom function","label":{"zoomFactor":{"world":"Zoom worldmap:","island":"Zoom island view:","town":"Zoom town view:"},"scaleChildren":{"description":"Let banners and symbols in normal size when zooming when zooming in this view:","world":"Worldmap","island":"Island view","town":"Town view"},"accessKeys":"This keys must be pressed to zoom with the mouse:"}},"messageSignature":{"title":"Message signature","label":{"useServerSignature":"Use local signature","placementTop":"Insert signature above cited messages","signatureText":{"global":"Global signature, which could be used on every world:","server":"Local signature, which only could be used on this world:"}}}}},"memberInfo":{"show":"Alliance info","reset":"Reset","lastReset":"Time since the last reset:","noReset":"No reset so far."},"unitInfo":{"button":"Troop information","header":"Troops in ","units":{"label":"Units in ","own":"Own units","friends":"Allied units","enemies":"Enemy units"},"ships":{"label":"Ships in ","own":"Own ships","friends":"Allied ships","enemies":"Enemy ships"}},"resourceInfo":{"dailyIncome":{"wood":"Daily production building material:","wine":"Daily production wine:","marble":"Daily production marble:","glass":"Daily production crystal glass:","sulfur":"Daily production sulphur:"}},"easyCircularMsg":{"getLink":"Save link for circular message","send":"Send circular message"},"replacedUrl":{"notification":{"header":"Attention!","text1":"You're going to open the link ","text2":". This happens on your own risk. Proceed?"}},"zoomFunction":{"zoomIn":"Zoom in","zoomFactor":"Zoom factor","zoomOut":"Zoom out"},"name":{"resource":{"gold":"Gold","wood":"Building Material","wine":"Wine","marble":"Marble","glass":"Crystal Glass","sulfur":"Sulphur"},"unit":{"swordsman":"Swordsman","phalanx":"Hoplite","archer":"Archer","marksman":"Sulphur Carabineer","mortar":"Mortar","slinger":"Slinger","catapult":"Catapult","ram":"Battering Ram","steamgiant":"Steam Giant","bombardier":"Balloon-Bombardier","cook":"Cook","medic":"Doctor","girocopter":"Gyrocopter","spearman":"Spearman"},"ship":{"ballista":"Ballista Ship","catapult":"Catapult Ship","flamethrower":"Fire Ship","mortar":"Mortar Ship","ram":"Ram Ship","steamboat":"Steam Ram","rocketship":"Rocket Ship","submarine":"Diving Boat","paddlespeedship":"Paddle Speedboat","ballooncarrier":"Balloon Carrier","tender":"Tender","transport":"Merchant Ship"}}}
- };
- /**********************************************************
- ***********************************************************
- ***** *****
- ***** Start of functions / variables for all Scripts. *****
- ***** *****
- ***********************************************************
- **********************************************************/
- /**
- * Sets unsafeWindow / window to win for easier access.
- */
- var win = typeof unsafeWindow != 'undefined' ? unsafeWindow : window;
- /**************************
- *** Debugging settings. ***
- **************************/
- // For more information about commands that are available for the Firebug console see http://getfirebug.com/wiki/index.php/Console_API.
- if(scriptInfo.debug && win.debugConsole) {
- var conTmp = win.debugConsole;
- } else {
- var conTmp = {
- // Non static functions are set to 'null'.
- log: function () { return false; },
- info: function () { return false; },
- warn: function () { return false; },
- error: function () { return false; },
- debug: function () { return false; },
- assert: function () { return false; },
- clear: function () { return false; },
- dir: function () { return false; },
- dirxml: function () { return false; },
- trace: function () { return false; },
- group: function () { return false; },
- groupCollapsed: function () { return false; },
- groupEnd: function () { return false; },
- time: function () { return false; },
- timeEnd: function () { return false; },
- profile: function () { return false; },
- profileEnd: function () { return false; },
- count: function () { return false; },
- exception: function () { return false; },
- table: function () { return false; }
- };
- }
- /**
- * Debugging console.
- */
- var con = conTmp;
- /********************************
- *** Functions for all Strings ***
- ********************************/
- /**
- * Replaces characters or whitespaces at the beginning of a string.
- *
- * @param String toRemove
- * A string containing the characters to remove (optional, if not set: trim whitespaces).
- *
- * @return String
- * The trimmed string.
- */
- String.prototype.ltrim = function(toRemove) {
- // Is there a string with the characters to remove?
- var special = !!toRemove;
- // Return the trimmed string.
- return special ? this.replace(new RegExp('^[' + toRemove + ']+'), '') : this.replace(/^\s+/, '');
- };
- /**
- * Replaces characters or whitespaces at the end of a string.
- *
- * @param String toRemove
- * A string containing the characters to remove (optional, if not set: trim whitespaces).
- *
- * @return String
- * The trimmed string.
- */
- String.prototype.rtrim = function(toRemove) {
- // Is there a string with the characters to remove?
- var special = !!toRemove;
- // Return the trimmed string.
- return special ? this.replace(new RegExp('[' + toRemove + ']+$'), '') : this.replace(/\s+$/, '');
- };
- /**
- * Replaces characters or whitespaces at the beginning and end of a string.
- *
- * @param String toRemove
- * A string containing the characters to remove (optional, if not set: trim whitespaces).
- *
- * @return String
- * The trimmed string.
- */
- String.prototype.trim = function(toRemove) {
- // Return the trimmed string.
- return this.ltrim(toRemove).rtrim(toRemove);
- };
- /**
- * Encodes HTML-special characters in a string.
- *
- * @return String
- * The encoded string.
- */
- String.prototype.encodeHTML = function() {
- // Set the characters to encode.
- var characters = {
- '&': '&',
- '"': '"',
- '\'': ''',
- '<': '<',
- '>': '>'
- };
- // Return the encoded string.
- return this.replace(/([\&"'<>])/g, function(string, symbol) { return characters[symbol]; });
- };
- /**
- * Decodes HTML-special characters in a string.
- *
- * @return String
- * The decoded string.
- */
- String.prototype.decodeHTML = function() {
- // Set the characters to decode.
- var characters = {
- '&': '&',
- '"': '"',
- ''': '\'',
- '<': '<',
- '>': '>'
- };
- // Return the decoded string.
- return this.replace(/("|'|<|>|&)/g, function(string, symbol) { return characters[symbol]; });
- };
- /**
- * Repeats a string a specified number of times.
- *
- * @param int nr
- * The number of times to repeat the string.
- *
- * @return String
- * The repeated string.
- */
- String.prototype.repeat = function(nr) {
- // Storage for the result.
- var ret = this;
- // Repeat the string.
- for(var i = 1; i < nr; i++) {
- ret += this;
- }
- // Return the string.
- return ret;
- };
- /********************************
- *** myGM / Updater / Language ***
- ********************************/
- /**
- * myGM for cross-browser compatibility of the GM_* functions. (use myGM.* instead of GM_*)
- * Also there are general used functions stored.
- */
- myGM = {
- /**
- * If it is possible to use the default GM_*Value functions, true, otherwise false.
- */
- canUseGmStorage: false,
- /**
- * If it is possible to use the default GM_getResourceText function, true, otherwise false.
- */
- canUseGmRessource: false,
- /**
- * If it is possible to use the default GM_xmlhttpRequest function, true, otherwise false.
- */
- canUseGmXhr: false,
- /**
- * If it is possible to use the localStorage, true, otherwise false.
- */
- canUseLocalStorage: false,
- /**
- * The prefix which schuld be added to the values stored in localStorage / cookies.
- */
- prefix: '',
- /**
- * Storage for the style sheets which will be added by the script.
- */
- styleSheets: new Array(),
- /**
- * Storage for the notification id.
- */
- notificationId: 0,
- /**
- * Init myGM.
- */
- init: function() {
- // Set the prefix for the script.
- this.prefix = 'script' + scriptInfo.id;
- // Set the possibility to use the different storages.
- this.canUseLocalStorage = !!win.localStorage;
- this.canUseGmStorage = !(typeof GM_getValue == 'undefined' || (typeof GM_getValue.toString == 'function' && GM_getValue.toString().indexOf('not supported') > -1))
- && !(typeof GM_setValue == 'undefined' || (typeof GM_setValue.toString == 'function' && GM_setValue.toString().indexOf('not supported') > -1))
- && !(typeof GM_deleteValue == 'undefined' || (typeof GM_deleteValue.toString == 'function' && GM_deleteValue.toString().indexOf('not supported') > -1))
- && !(typeof GM_listValues == 'undefined' || (typeof GM_listValues.toString == 'function' && GM_listValues.toString().indexOf('not supported') > -1));
- // Set the possibility to use the GM_resource.
- this.canUseGmRessource = !(typeof GM_getResourceText == 'undefined' || (typeof GM_getResourceText.toString == 'function' && GM_getResourceText.toString().indexOf('not supported') > -1));
- // Set the possibillity to use the GM_xhr.
- this.canUseGmXhr = !(typeof GM_xmlhttpRequest == 'undefined' || (typeof GM_xmlhttpRequest.toString == 'function' && GM_xmlhttpRequest.toString().indexOf('not supported') > -1));
- // Set the close image. It is stored as a data URI. If you copy it to your browser, a red cross (16px * 16px) will be shown.
- var closeImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIhSURBVDjLlZPrThNRFIWJicmJz6BWiYbIkYDEG0JbBiitDQgm0PuFXqSAtKXtpE2hNuoPTXwSnwtExd6w0pl2OtPlrphKLSXhx07OZM769qy19wwAGLhM1ddC184+d18QMzoq3lfsD3LZ7Y3XbE5DL6Atzuyilc5Ciyd7IHVfgNcDYTQ2tvDr5crn6uLSvX+Av2Lk36FFpSVENDe3OxDZu8apO5rROJDLo30+Nlvj5RnTlVNAKs1aCVFr7b4BPn6Cls21AWgEQlz2+Dl1h7IdA+i97A/geP65WhbmrnZZ0GIJpr6OqZqYAd5/gJpKox4Mg7pD2YoC2b0/54rJQuJZdm6Izcgma4TW1WZ0h+y8BfbyJMwBmSxkjw+VObNanp5h/adwGhaTXF4NWbLj9gEONyCmUZmd10pGgf1/vwcgOT3tUQE0DdicwIod2EmSbwsKE1P8QoDkcHPJ5YESjgBJkYQpIEZ2KEB51Y6y3ojvY+P8XEDN7uKS0w0ltA7QGCWHCxSWWpwyaCeLy0BkA7UXyyg8fIzDoWHeBaDN4tQdSvAVdU1Aok+nsNTipIEVnkywo/FHatVkBoIhnFisOBoZxcGtQd4B0GYJNZsDSiAEadUBCkstPtN3Avs2Msa+Dt9XfxoFSNYF/Bh9gP0bOqHLAm2WUF1YQskwrVFYPWkf3h1iXwbvqGfFPSGW9Eah8HSS9fuZDnS32f71m8KFY7xs/QZyu6TH2+2+FAAAAABJRU5ErkJggg%3D%3D';
- // Set the notification style.
- this.addStyle(
- "." + this.prefix + "notificationBackground { z-index: 1000000000000; position: fixed; visibility: visible; top: 0px; left: 0px; width: 100%; height: 100%; padding: 0; background-color: #000; opacity: .7; } \
- ." + this.prefix + "notificationPanelContainer { z-index: 1000000000001; position: fixed; visibility: visible; top: 100px; left: 50%; width: 500px; height: 370px; margin-left: -250px; padding: 0; text-align: left; color: #333; font: 12px Arial,Helvetica,sans-serif; } \
- ." + this.prefix + "notificationPanel { position: relative; top: 0px; left: 0px; background-color: transparent; border: 0 none; overflow: hidden; } \
- ." + this.prefix + "notificationPanelHeader { height: 39px; background: none repeat scroll 0 0 transparent; font-weight: bold; line-height: 2; white-space: nowrap; } \
- ." + this.prefix + "notificationPanelHeaderL { } \
- ." + this.prefix + "notificationPanelHeaderR { } \
- ." + this.prefix + "notificationPanelHeaderM { height: 24px; background-color: #999; padding: 5px; border: 3px solid #000; border-radius: 5px; color: #811709; line-height: 1.34em; font-size: 15pt; } \
- ." + this.prefix + "notificationPanelBody { max-height: 311px; height: 100%; background: none repeat scroll 0 0 transparent; } \
- ." + this.prefix + "notificationPanelBodyL { } \
- ." + this.prefix + "notificationPanelBodyR { } \
- ." + this.prefix + "notificationPanelBodyM { height: 100%; background-color: #F5F5F5; border-left: 3px solid #000; border-right: 3px solid #000; border-top-left-radius: 5px; border-top-right-radius: 5px; padding: 0 10px; font-size: 14px; } \
- ." + this.prefix + "notificationPanelBodyMTop { max-height: 100px; line-height: 2; } \
- ." + this.prefix + "notificationPanelBodyMTop b { line-height: 3.5; font-size: 110%; } \
- ." + this.prefix + "notificationPanelBodyM a { color: #811709; font-weight: bold; } \
- ." + this.prefix + "notificationPanelBodyM h2 { font-weight: bold; } \
- ." + this.prefix + "notificationPanelBodyMContent { max-height: 265px; padding: 10px; background-color: #FFF; border: 1px dotted #4D4D4D; font: 14px Arial,Helvetica,sans-serif; color: #333; border-collapse: separate; overflow-y:auto; margin-top: 5px; } \
- ." + this.prefix + "notificationPanelBodyMBottom { max-height: 170px; padding: 10px; background-color: #FFF; border: 1px dotted #4D4D4D; font: 14px Arial,Helvetica,sans-serif; color: #333; border-collapse: separate; overflow-y:auto; } \
- ." + this.prefix + "notificationPanelBodyPlaceholder { height: 20px; } \
- ." + this.prefix + "notificationPanelFooter { height: 20px; background: none repeat scroll 0 0 transparent; } \
- ." + this.prefix + "notificationPanelFooterL { } \
- ." + this.prefix + "notificationPanelFooterR { } \
- ." + this.prefix + "notificationPanelFooterM { background-color: #F5F5F5; border-bottom: 3px solid #000; border-left: 3px solid #000; border-right: 3px solid #000; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; padding: 3px 0 2px 3px; font-size: 77%; } \
- ." + this.prefix + "notificationPanelClose { cursor: pointer; position: absolute; top: 10px; right: 10px; width: 16px; height: 16px; background-image: url('" + closeImage + "'); } \
- ." + this.prefix + "notificationPanelButtonWrapper { bottom: -4px; position: absolute; margin: 10px auto; width: 100%; text-align: center; } \
- ." + this.prefix + "notificationPanelButton { background-color: #DADEDE; border-color: #C0C0C0 #4D4D4D #4D4D4D #C0C0C0; border-style: double; border-width: 3px; border-radius: 5px; cursor: pointer; display: inline; font-weight: bold; margin: 0px 5px; padding: 2px 10px; text-align: center; font-size: 12px; width: 100px; } \
- ." + this.prefix + "notificationPanelButton:hover { color: #444; } \
- ." + this.prefix + "notificationPanelButton:active { border-color: #4D4D4D #C0C0C0 #C0C0C0 #4D4D4D; border-style: double; border-width: 3px; padding: 3px 10px 1px; } \
- ." + this.prefix + "notificationPanelButtonConfirm { } \
- ." + this.prefix + "notificationPanelButtonAbort { }",
- 'notification'
- );
- // Set the updater style.
- this.addStyle(
- "." + this.prefix + "updateTable { border-collapse: separate; border-spacing: 2px; } \
- ." + this.prefix + "updateDataType { width: 100px; padding: 5px 0px 5px 5px; border: 1px solid #999; } \
- ." + this.prefix + "updateDataInfo { width: 300px; padding: 5px 5px 5px 20px; border: 1px solid #999; } \
- ." + this.prefix + "updateDataInfo ul li { list-style: disc outside none; }",
- 'updater'
- );
- },
- /**
- * Store a value specified by a key.
- *
- * @param String key
- * The key of the value.
- * @param mixed value
- * The value to store.
- */
- setValue: function(key, value) {
- var toStore = '';
- // Stringify the value to store also arrays.
- toStore = JSON.stringify(value);
- // If the use of the default GM_setValue ist possible, use it.
- if(this.canUseGmStorage) {
- // Store the value.
- GM_setValue(key, toStore);
- // Otherwise use the local storage if possible.
- } else if(this.canUseLocalStorage) {
- // Store the value.
- win.localStorage.setItem(this.prefix + key, toStore);
- // Otherwise use cookies.
- } else {
- // Prepare the cookie name and value.
- var data = escape(this.prefix + key) + '=' + escape(toStore);
- // Set the expire date to January 1st, 2020.
- var expire = 'expires=' + (new Date(2020, 0, 1, 0, 0, 0, 0)).toGMTString();
- // Set the path to root.
- var path = 'path=/';
- // Made the cookie accessible from all servers.
- var domain = 'domain=ikariam.com';
- // Set the cookie.
- win.document.cookie = data + ';' + expire + ';' + path + ';' + domain;
- }
- },
- /**
- * Get a value and return it.
- *
- * @param String key
- * The key of the value.
- * @param mixed defaultValue
- * The value which is set if the value is not set.
- *
- * @return mixed
- * The stored value.
- */
- getValue: function(key, defaultValueOld) {
- defaultValue = JSON.stringify(defaultValueOld);
- // Storage for the value.
- var value = defaultValue;
- // If the use of the default GM_getValue ist possible, use it.
- if(this.canUseGmStorage) {
- // Get the value.
- value = GM_getValue(key, defaultValue);
- // Otherwise use the local storage if possible.
- } else if(this.canUseLocalStorage) {
- // Get the value.
- var valueTmp = win.localStorage.getItem(this.prefix + key);
- // If the value is not set, let the default value set.
- if(valueTmp) {
- value = valueTmp;
- }
- // Otherwise use cookies.
- } else {
- // Get all cookies.
- var allCookies = document.cookie.split("; ");
- // Loop over all cookies.
- for(var i = 0; i < allCookies.length; i++) {
- // Get the key and value of a cookie.
- var oneCookie = allCookies[i].split("=");
- // If the key is the correct key, get the value.
- if(oneCookie[0] == escape(this.prefix + key)) {
- // Get the value and abort the loop.
- value = unescape(oneCookie[1]);
- break;
- }
- }
- }
- // Return the value (parsed for the correct return type).
- return JSON.parse(value);
- },
- /**
- * Delete a value specified by a key.
- *
- * @param String key
- * The key of the value.
- */
- deleteValue: function(key) {
- // If the use of the default GM_deleteValue ist possible, use it.
- if(this.canUseGmStorage) {
- // Delete the value.
- GM_deleteValue(key);
- // Otherwise use the local storage if possible.
- } else if(this.canUseLocalStorage) {
- // Remove the value.
- win.localStorage.removeItem(this.prefix + key);
- // Otherwise use cookies.
- } else {
- // Prepare the cookie name.
- var data = escape(this.prefix + key) + '=';
- // Set the expire date to January 1st, 2000 (this will delete the cookie).
- var expire = 'expires=' + (new Date(2000, 0, 1, 0, 0, 0, 0)).toGMTString();
- // Set the path to root.
- var path = 'path=/';
- // Made the cookie accessible from all servers.
- var domain = 'domain=ikariam.com';
- // Set the cookie.
- win.document.cookie = data + ';' + expire + ';' + path + ';' + domain;
- }
- },
- /**
- * Returns an array with the keys of all values stored by the script.
- *
- * @return mixed[]
- * The array with all keys.
- */
- listValues: function() {
- // Create an array for the storage of the values keys.
- var key = new Array();
- // If the use of the default GM_listValues ist possible, use it.
- if(this.canUseGmStorage) {
- // Store the key(s) to the array.
- key = GM_listValues();
- // Otherwise use the local storage if possible.
- } else if(this.canUseLocalStorage) {
- // Loop over all stored values.
- for(var i = 0; i < win.localStorage.length; i++) {
- // Get the key name of the key with the number i.
- var keyName = win.localStorage.key(i);
- // If the value is set by the script, push the key name to the array.
- if(keyName.indexOf(this.prefix) != -1) {
- key.push(keyName.replace(this.prefix, ''));
- }
- }
- // Otherwise use cookies.
- } else {
- // Get all cookies.
- var allCookies = document.cookie.split("; ");
- // Loop over all cookies.
- for(var i = 0; i < allCookies.length; i++) {
- // Get the key name of a cookie.
- var keyName = unescape(allCookies[i].split("=")[0]);
- // If the key value is set by the script, push the key name to the array.
- if(keyName.indexOf(this.prefix) != -1) {
- key.push(keyName.replace(this.prefix, ''));
- }
- }
- }
- // Return all keys.
- return key;
- },
- /**
- * Adds a style element to the head of the page and return it.
- *
- * @param String styleRules
- * The style rules to be set.
- * @param String id
- * An id for the style set, to have the possibility to delete it. (optional, if none is set, the stylesheet is not stored)
- * @param boolean overwrite
- * If a style with id should overwrite an existing style.
- *
- * @return boolean
- * If the stylesheet was stored with the id.
- */
- addStyle: function(styleRules, id, overwrite) {
- // If the element was stored is saved here.
- var storedWithId = false;
- // If overwrite, remove the old style sheet.
- if(overwrite && overwrite == true) {
- this.removeStyle(id);
- }
- // If the stylesheet doesn't exists.
- if(!id || (id && !this.styleSheets[id])) {
- // Create a new style element and set the style rules.
- var style = this.addElement('style', document.head);
- style.type = 'text/css';
- style.innerHTML = styleRules;
- // If an id is set, store it.
- if(id) {
- this.styleSheets[id] = style;
- storedWithId = true;
- }
- }
- // Return if the stylesheet was stored with an id.
- return storedWithId;
- },
- /**
- * Removes a style element set by the script.
- *
- * @param String id
- * The id of the stylesheet to delete.
- *
- * @return boolean
- * If the stylesheet could be deleted.
- */
- removeStyle: function(id) {
- // Stores if the stylesheet could be removed.
- var removed = false;
- // If there is an id set and a stylesheet with the id exists.
- if(id && this.styleSheets[id]) {
- // Remove the stylesheet from the page.
- document.head.removeChild(this.styleSheets[id]);
- // Remove the stylesheet from the array.
- delete this.styleSheets[id];
- // Set removed to true.
- removed = true;
- }
- // Return if the stylesheet could be removed.
- return removed;
- },
- /**
- * Returns the content of a resource parsed with JSON.parse.
- *
- * @param String name
- * The name of the resource to parse.
- */
- getResourceParsed: function(name) {
- // Storage for the response text.
- var responseText = '';
- // Function for safer parsing.
- var safeParse = function(key, value) {
- // If the value is a function, return just the string, so it is not executable.
- if(typeof value === 'function' || Object.prototype.toString.apply(value) === '[object function]') {
- return value.toString();
- }
- // Return the value.
- return value;
- };
- // If the use of the default GM_getRessourceText ist possible, use it.
- if(this.canUseGmRessource) {
- // Set the parsed text.
- responseText = GM_getResourceText(name);
- // Otherwise perform a xmlHttpRequest.
- } else {
- // Perform the xmlHttpRequest.
- responseText = this.xhr({
- method: 'GET',
- url: 'http://resources.ikascripts.de/' + scriptInfo.id + '/v' + scriptInfo.version + '/' + name + '.json',
- headers: { 'User-agent': navigator.userAgent, 'Accept': 'text/html' },
- synchronous: true,
- onload: function(response) { return false; }
- });
- }
- return JSON.parse(responseText.trim(), safeParse);
- },
- /**
- * Makes a cross-site XMLHttpRequest.
- *
- * @param mixed[] args
- * The arguments the request needs. (specified here: http://wiki.greasespot.net/GM_xmlhttpRequest)
- */
- xhr: function(args) {
- // Storage for the result of the request.
- var responseText;
- // Check if all required data is given.
- if(!args.method || !args.url || !args.onload) {
- return false;
- }
- // If the use of the default GM_xmlhttpRequest ist possible, use it.
- if(this.canUseGmXhr) {
- // Sent the request.
- var response = GM_xmlhttpRequest(args);
- // Get the response text.
- responseText = response.responseText;
- // Otherwise show a hint for the missing possibility to fetch the data.
- } else {
- // Storage if the link fetches metadata from userscripts.org
- var usoUpdate = (args.url.search(/^http:\/\/userscripts.org\/scripts\/source\/[0-9]+\.meta\.js$/i) != -1);
- var isJSON = (args.url.search(/\.json$/i) != -1);
- // If it is a metadata request.
- if(usoUpdate) {
- // Set the update interval to max.
- this.setValue('updater_updateInterval', 28 * 24 * 60 * 60);
- // Set the notification text.
- var notificationText = {
- header: Language.$('default_update_notPossible_header'),
- body: Language.$('default_update_notPossible_text1') + '<a href="http://userscripts.org/scripts/show/' + scriptInfo.id + '" target="_blank" >' + scriptInfo.name + '</a>' + Language.$('default_update_notPossible_text2') + scriptInfo.version + Language.$('default_update_notPossible_text3')
- };
- // Show a notification.
- this.notification(notificationText);
- responseText = true;
- // Otherwise if it is JSON.
- } else if(isJSON) {
- // Do the request with a string indicating the error.
- args.onload('{ "is_error": true }');
- // Return a string indicating the error.
- responseText = '{ "is_error": true }';
- // Otherwise.
- } else {
- responseText = false;
- }
- }
- // Return the responseText.
- return responseText;
- },
- /**
- * Shows a notification to the user.
- *
- * Possible notification texts:
- * text.header (optional)
- * text.body or text.bodyTop & text.bodyBottom
- * text.confirm (optional)
- * text.abort (optional)
- *
- * @param String[] text
- * The notification texts.
- * @param function[] callback
- * The callbacks for confirm and abort. (optional, default: close panel)
- *
- * @return int
- * The notification id.
- */
- notification: function(text, callback) {
- // Get the notification id.
- this.notificationId += 1;
- var notificationId = this.notificationId;
- // Create the background and the container.
- myGM.addElement('div', document.body, 'notificationBackground' + notificationId, 'notificationBackground', null, true);
- var notificationPanelContainer = myGM.addElement('div', document.body, 'notificationPanelContainer' + notificationId, 'notificationPanelContainer', null, true);
- var notificationPanel = myGM.addElement('div', notificationPanelContainer, 'notificationPanel' + notificationId, 'notificationPanel', null, true);
- // Create the notification panel header.
- var notificationPanelHeader = myGM.addElement('div', notificationPanel, 'notificationPanelHeader' + notificationId, 'notificationPanelHeader', null, true);
- var notificationPanelHeaderL = myGM.addElement('div', notificationPanelHeader, 'notificationPanelHeaderL' + notificationId, 'notificationPanelHeaderL', null, true);
- var notificationPanelHeaderR = myGM.addElement('div', notificationPanelHeaderL, 'notificationPanelHeaderR' + notificationId, 'notificationPanelHeaderR', null, true);
- var notificationPanelHeaderM = myGM.addElement('div', notificationPanelHeaderR, 'notificationPanelHeaderM' + notificationId, 'notificationPanelHeaderM', null, true);
- // Create the notification panel body.
- var notificationPanelBody = myGM.addElement('div', notificationPanel, 'notificationPanelBody' + notificationId, 'notificationPanelBody', null, true);
- var notificationPanelBodyL = myGM.addElement('div', notificationPanelBody, 'notificationPanelBodyL' + notificationId, 'notificationPanelBodyL', null, true);
- var notificationPanelBodyR = myGM.addElement('div', notificationPanelBodyL, 'notificationPanelBodyR' + notificationId, 'notificationPanelBodyR', null, true);
- var notificationPanelBodyM = myGM.addElement('div', notificationPanelBodyR, 'notificationPanelBodyM' + notificationId, 'notificationPanelBodyM', null, true);
- if(text.body) {
- var notificationPanelBodyMContent = myGM.addElement('div', notificationPanelBodyM, 'notificationPanelBodyMContent' + notificationId, 'notificationPanelBodyMContent', null, true);
- } else {
- var notificationPanelBodyMTop = myGM.addElement('div', notificationPanelBodyM, 'notificationPanelBodyMTop' + notificationId, 'notificationPanelBodyMTop', null, true);
- var notificationPanelBodyMBottom = myGM.addElement('div', notificationPanelBodyM, 'notificationPanelBodyMBottom' + notificationId, 'notificationPanelBodyMBottom', null, true);
- }
- myGM.addElement('div', notificationPanelBodyM, 'notificationPanelBodyPlaceholder' + notificationId, 'notificationPanelBodyPlaceholder', null, true);
- // Create the notification panel footer.
- var notificationPanelFooter = myGM.addElement('div', notificationPanel, 'notificationPanelFooter' + notificationId, 'notificationPanelFooter', null, true);
- var notificationPanelFooterL = myGM.addElement('div', notificationPanelFooter, 'notificationPanelFooterL' + notificationId, 'notificationPanelFooterL', null, true);
- var notificationPanelFooterR = myGM.addElement('div', notificationPanelFooterL, 'notificationPanelFooterR' + notificationId, 'notificationPanelFooterR', null, true);
- var notificationPanelFooterM = myGM.addElement('div', notificationPanelFooterR, 'notificationPanelFooterM' + notificationId, 'notificationPanelFooterM', null, true);
- // Create the button wrapper.
- var notificationPanelButtonWrapper = myGM.addElement('div', notificationPanel, 'notificationPanelButtonWrapper' + notificationId, 'notificationPanelButtonWrapper', null, true);
- // Create the confirm button.
- var notificationPanelConfirm = myGM.addElement('input', notificationPanelButtonWrapper, 'notificationPanelConfirm' + notificationId, new Array('notificationPanelButton', 'notificationPanelButtonConfirm'), null, true);
- notificationPanelConfirm.type = 'button';
- notificationPanelConfirm.value = text.confirm ? text.confirm : Language.$('default_notification_button_confirm');
- // Create the abort button if needed.
- if(callback && callback.abort) {
- var notificationPanelAbort = myGM.addElement('input', notificationPanelButtonWrapper, 'notificationPanelAbort' + notificationId, new Array('notificationPanelButton', 'notificationPanelButtonAbort'), null, true);
- notificationPanelAbort.type = 'button';
- notificationPanelAbort.value = text.abort ? text.abort : Language.$('default_notification_button_abort');
- }
- // Insert the texts into header, body and footer.
- notificationPanelHeaderM.innerHTML = (text.header ? text.header : Language.$('default_notification_header')) + '<div id="' + this.prefix + 'notificationPanelClose' + notificationId + '" class="' + this.prefix + 'notificationPanelClose"></div>';
- notificationPanelFooterM.innerHTML = scriptInfo.name + ' v' + scriptInfo.version;
- if(text.body) {
- notificationPanelBodyMContent.innerHTML = text.body;
- } else {
- notificationPanelBodyMTop.innerHTML = text.bodyTop ? text.bodyTop : '';
- notificationPanelBodyMBottom.innerHTML = text.bodyBottom ? text.bodyBottom : '';
- }
- // Function to close the notification panel.
- var closeNotificationPanel = function() {
- // Remove the notification background.
- document.body.removeChild(myGM.$('#' + myGM.prefix + 'notificationBackground' + notificationId));
- // Remove the notification panel.
- document.body.removeChild(myGM.$('#' + myGM.prefix + 'notificationPanelContainer' + notificationId));
- };
- // Add event listener to the buttons to close / install.
- this.$('#' + this.prefix + 'notificationPanelClose' + notificationId).addEventListener('click', closeNotificationPanel, false);
- if(callback && callback.confirm) {
- notificationPanelConfirm.addEventListener('click', function() { closeNotificationPanel(); callback.confirm(); }, false);
- } else {
- notificationPanelConfirm.addEventListener('click', closeNotificationPanel, false);
- }
- if(callback && callback.abort) {
- notificationPanelAbort.addEventListener('click', function() { closeNotificationPanel(); callback.abort(); }, false);
- }
- return notificationId;
- },
- /**
- * Gets the first matching child element by a query and returns it.
- *
- * @param String query
- * The query for the element.
- * @param element parent
- * The parent element. (optional, default document)
- *
- * @return element
- * The element.
- */
- $: function(query, parent) {
- return this.$$(query, parent)[0];
- },
- /**
- * Gets all matching child elements by a query and returns them.
- *
- * @param String query
- * The query for the elements.
- * @param element parent
- * The parent element. (optional, default document)
- *
- * @return element[]
- * The elements.
- */
- $$: function(query, parent) {
- // If there is no parent set, set it to document.
- if(!parent) parent = document;
- // Return the elements.
- return Array.prototype.slice.call(parent.querySelectorAll(query));
- },
- /**
- * Creates a new element and adds it to a parent.
- *
- * @param String type
- * The type of the new element.
- * @param element parent
- * The parent of the new element.
- * @param int id
- * The last part of the id of the element. (optional, if not set, no id will be set)
- * @param String || String[] classes
- * The class(es) of the element. (optional, if not set, no class will be set)
- * @param mixed[] style
- * The styles of the element. (optional, if not set, no style will be set)
- * @param boolean || boolean[] hasPrefix
- * If no prefix should be used. (optional, if not set, a prefix will be used for id and no prefix will be used for classes)
- * @param element nextSib
- * The next sibling of the element. (optional, if not set, the element will be added at the end)
- *
- * @return element
- * The new element.
- */
- addElement: function(type, parent, id, classes, style, hasPrefix, nextSib) {
- // Create the new Element.
- var newElement = document.createElement(type);
- // If there is a id, set it.
- if(id) {
- // Get the id prefix.
- var idPrefix = !(hasPrefix == false || (hasPrefix && hasPrefix.id == false)) ? this.prefix : '';
- // Set the id.
- newElement.id = idPrefix + id;
- }
- // Add all classes.
- if(classes && classes != '') {
- // Get the class prefix.
- var classPrefix = !!(hasPrefix == true || (hasPrefix && hasPrefix.classes == true)) ? this.prefix : '';
- // Set the class(es).
- if(typeof classes == 'string') {
- newElement.classList.add(classPrefix + classes);
- } else {
- for(var i = 0; i < classes.length; i++) {
- newElement.classList.add(classPrefix + classes[i]);
- }
- }
- }
- if(style) {
- for(var i = 0; i < style.length; i++) {
- newElement.style[style[i][0]] = style[i][1];
- }
- }
- // If there is the next sibling defined, insert it before it.
- if(nextSib) {
- parent.insertBefore(newElement, nextSib);
- // Otherwise insert it at the end.
- } else {
- parent.appendChild(newElement);
- }
- // Return the new element.
- return newElement;
- }
- };
- /**
- * Functions for updater.
- */
- Updater = {
- /**
- * Stores if the update was instructed by the user.
- */
- manualUpdate: false,
- /**
- * Init the Updater.
- */
- init: function() {
- // Get the difference between now and the last check.
- var lastCheck = myGM.getValue('updater_lastUpdateCheck', 0);
- var millis = (new Date()).getTime();
- var diff = millis - lastCheck;
- // If the module is active and the last update is enough time before, check for updates.
- if(myGM.getValue('module_updateActive', true) && diff > myGM.getValue('updater_updateInterval', 3600) * 1000) {
- // No manual Update.
- this.manualUpdate = false;
- // Check for Updates.
- this.checkForUpdates();
- // Set the time for the last update check to now.
- myGM.setValue('updater_lastUpdateCheck', millis + '');
- }
- },
- /**
- * Search manually for updates.
- */
- doManualUpdate: function() {
- // Manual Update.
- Updater.manualUpdate = true;
- // Check for Updates.
- Updater.checkForUpdates();
- // Set the time for the last update check to now.
- myGM.setValue('updater_lastUpdateCheck', (new Date()).getTime() + '');
- },
- /**
- * Check for updates for the Script.
- *
- * @return boolean
- * If there is a newer version.
- */
- checkForUpdates: function() {
- // Send a request to the userscripts.org server to get the metadata of the script to check if there is a new Update.
- myGM.xhr({
- method: 'GET',
- url: 'https://greasyfork.org/scripts/' + scriptInfo.id + '/code.meta.js',
- headers: {'User-agent': 'Mozilla/5.0', 'Accept': 'text/html'},
- onload: function(response) {
- // Extract the metadata from the response.
- var metadata = Updater.formatMetadata(response.responseText);
- // If a new Update is available and the update hint should be shown.
- if(Updater.newerVersion(scriptInfo.version, metadata.version2) && (myGM.getValue('updater_hideUpdate', scriptInfo.version) != metadata.version2 || Updater.manualUpdate)) {
- // Show update dialogue.
- Updater.showUpdateInfo(metadata);
- // If there is no new update and it was a manual update show hint.
- } else if(Updater.manualUpdate) {
- // Set the notification text.
- var notificationText = {
- header: Language.$('default_update_noNewExists_header'),
- body: Language.$('default_update_noNewExists_text1') + '<a href="http://userscripts.org/scripts/show/' + scriptInfo.id + '" target="_blank" >' + scriptInfo.name + '</a>' + Language.$('default_update_noNewExists_text2') + scriptInfo.version + Language.$('default_update_noNewExists_text3')
- };
- // Show a notification.
- myGM.notification(notificationText);
- }
- }
- });
- },
- /**
- * Show the update information panel.
- *
- * @param String versionOld
- * The old version number.
- * @param String versionNew
- * The new version number.
- * @param int maxPartsToCompare
- * The number of parts to compare at most. (optional, default "compare all parts")
- *
- * @return boolean
- * If a new version is available.
- */
- newerVersion: function(versionOld, versionNew, maxPartsToCompare) {
- // Stores if a new version is available.
- var newVersion = false;
- // Force both versions to be a string.
- versionOld += '';
- versionNew += '';
- // The parts of the versions.
- var versionOldParts = versionOld.split('.');
- var versionNewParts = versionNew.split('.');
- // The bigger number of parts of the versions.
- var biggerNumberOfParts = versionOldParts.length > versionNewParts.length ? versionOldParts.length : versionNewParts.length;
- // If all parts should be compared, set maxPartsToCompare to all parts.
- if(!maxPartsToCompare || maxPartsToCompare < 1) {
- maxPartsToCompare = biggerNumberOfParts + 1;
- }
- // Loop over all parts of the version with less parts.
- for(var i = 0; i < biggerNumberOfParts; i++) {
- // Get the value of the parts.
- var versionPartOld = parseInt(versionOldParts[i] || 0);
- var versionPartNew = parseInt(versionNewParts[i] || 0);
- // If the old part is smaller than the new, return true.
- if(versionPartOld < versionPartNew) {
- newVersion = true;
- break;
- // Else if the old part is bigger than the new it is now new version; return false.
- } else if(versionPartOld > versionPartNew || i == maxPartsToCompare - 1) {
- newVersion = false;
- break;
- }
- }
- // No new version, return false.
- return newVersion;
- },
- /**
- * Show the update information panel.
- *
- * @param mixed[] metadata
- * Array with formated metadata
- */
- showUpdateInfo: function(metadata) {
- // Get the update history.
- var updateHistory = this.extractUpdateHistory(metadata);
- // Set the notification text.
- var notificationText = {
- header: Language.$('default_update_possible_header'),
- bodyTop: Language.$('default_update_possible_text1') + '<a href="http://userscripts.org/scripts/show/' + scriptInfo.id + '" target="_blank" >' + scriptInfo.name + '</a>' + Language.$('default_update_possible_text2') + '.<br>' + Language.$('default_update_possible_text3') + scriptInfo.version + Language.$('default_update_possible_text4') + metadata.version + '.<br> <b><u>' + Language.$('default_update_possible_history') + '</u></b>',
- bodyBottom: this.formatUpdateHistory(updateHistory),
- confirm: Language.$('default_update_possible_button_install'),
- abort: Language.$('default_update_possible_button_hide')
- };
- // Set the notification callback.
- var notificationCallback = {
- confirm: function() { win.top.location.href = 'http://userscripts.org/scripts/source/' + scriptInfo.id + '.user.js'; },
- abort: function() { myGM.setValue('updater_hideUpdate', metadata.version + ''); }
- };
- // Show a notification.
- myGM.notification(notificationText, notificationCallback);
- },
- /**
- * Format the given metadata.
- *
- * @param String metadata
- * The metadata to format.
- *
- * @return String[]
- * The formated metadata as array.
- */
- formatMetadata: function(metadataIn) {
- // Create an array for the formated metadata.
- var metadataOut = new Array();
- // Extract the tags from the metadata.
- var innerMeta = metadataIn.match(/\/\/ ==UserScript==((.|\n|\r)*?)\/\/ ==\/UserScript==/)[0];
- // If there are some tags.
- if(innerMeta) {
- // Extract all tags.
- var tags = innerMeta.match(/\/\/ @(.*?)(\n|\r)/g);
- // Loop over all tags.
- for(var i = 0; i < tags.length; i++) {
- // Extract the data from the tag.
- var tmp = tags[i].match(/\/\/ @(.*?)\s+(.*)/);
- // If there is no data with this tag create a new array to store all data with this tag.
- if(!metadataOut[tmp[1]]) {
- metadataOut[tmp[1]] = new Array(tmp[2]);
- // Otherwise add the data to the existing array.
- } else {
- metadataOut[tmp[1]].push(tmp[2]);
- }
- }
- }
- // Return the formated metadata.
- return metadataOut;
- },
- /**
- * Extract the update history from the metadata.
- *
- * @param String[] metadata
- * Array with the formated metadata.
- *
- * @return mixed[]
- * The extracted update history.
- */
- extractUpdateHistory: function(metadata) {
- // Create variable to store the update history.
- var updateHistory = new Array();
- // Loop over all update history data.
- for(var i = 0; i < metadata['history'].length; i++) {
- // Get the information from the update history data.
- var tmp = metadata['history'][i].match(/^(\S+)\s+(\S+)\s+(.*)$/);
- // If there is no array for this version create one.
- if(!updateHistory[tmp[1]]) {
- updateHistory[tmp[1]] = new Array();
- }
- // If it is a feature store it to feature in this version.
- if(tmp[2] == 'Feature:') {
- if(!updateHistory[tmp[1]]['feature']) {
- updateHistory[tmp[1]]['feature'] = new Array(tmp[3]);
- } else {
- updateHistory[tmp[1]]['feature'].push(tmp[3]);
- }
- // If it is a bugfix store it to bugfix in this version.
- } else if(tmp[2] == 'Bugfix:') {
- if(!updateHistory[tmp[1]]['bugfix']) {
- updateHistory[tmp[1]]['bugfix'] = new Array(tmp[3]);
- } else {
- updateHistory[tmp[1]]['bugfix'].push(tmp[3]);
- }
- // Otherwise store it to other in this version.
- } else {
- if(!updateHistory[tmp[1]]['other']) {
- updateHistory[tmp[1]]['other'] = new Array(tmp[2] + " " + tmp[3]);
- } else {
- updateHistory[tmp[1]]['other'].push(tmp[2] + " " + tmp[3]);
- }
- }
- }
- // Return the update history.
- return updateHistory;
- },
- /**
- * Format the update history.
- *
- * @param mixed[] updateHistory
- * The update history.
- *
- * @return String
- * The formated update history.
- */
- formatUpdateHistory: function(updateHistory) {
- // Get the labels for the types.
- var types = {
- feature: Language.$('default_update_possible_type_feature'),
- bugfix: Language.$('default_update_possible_type_bugfix'),
- other: Language.$('default_update_possible_type_other')
- };
- // Create a var for the formated update history.
- var formatedUpdateHistory = '';
- // Loop over all versions.
- for(var version in updateHistory) {
- // Create a headline for each version and start a table.
- formatedUpdateHistory += '<h2>v ' + version + '</h2><br><table class="' + myGM.prefix + 'updateTable"><tbody>';
- // Loop over all types.
- for(var type in updateHistory[version]) {
- // Create a table row for each type and start a list for the elements.
- formatedUpdateHistory += '<tr><td class="' + myGM.prefix + 'updateDataType">' + types[type] + '</td><td class="' + myGM.prefix + 'updateDataInfo"><ul>';
- // Loop over the elements and add them to the list.
- for(var i = 0 ; i < updateHistory[version][type].length; i++) {
- formatedUpdateHistory += '<li>' + updateHistory[version][type][i] + '</li>';
- }
- // End the list.
- formatedUpdateHistory += '</ul></td></tr>';
- }
- // End the table.
- formatedUpdateHistory += '</tbody></table><br>';
- }
- // Return the formated update history.
- return formatedUpdateHistory;
- }
- };
- /**
- * Functions for language.
- */
- Language = {
- /**
- * The name of the language which is actually set.
- */
- name: 'English',
- /**
- * The text of the used language.
- */
- text: null,
- /**
- * Init the language and set the used language code.
- */
- init: function() {
- // Get the language code.
- var langCode = top.location.host.match(/^s[0-9]+-([a-zA-Z]+)\.ikariam\.gameforge\.com$/)[1];
- // Set the language name.
- this.setLangName(!!langCode ? langCode : 'en');
- // Set the text in the used language.
- this.setText();
- },
- /**
- * Set the name of the used language.
- *
- * @param String code
- * The laguage code.
- */
- setLangName: function(code) {
- // All languages.
- var languageName = {
- ae: 'Arabic', ar: 'Spanish', ba: 'Bosnian', bg: 'Bulgarian', br: 'Portuguese', by: 'Russian',
- cl: 'Spanish', cn: 'Chinese', co: 'Spanish', cz: 'Czech', de: 'German', dk: 'Danish',
- ee: 'Estonian', en: 'English', es: 'Spanish', fi: 'Finish', fr: 'French', gr: 'Greek',
- hk: 'Chinese', hr: 'Bosnian', hu: 'Hungarian', id: 'Indonesian', il: 'Hebrew', it: 'Italian',
- kr: 'Korean', lt: 'Lithuanian', lv: 'Latvian', mx: 'Spanish', nl: 'Dutch', no: 'Norwegian',
- pe: 'Spanish', ph: 'Filipino', pk: 'Urdu', pl: 'Polish', pt: 'Portuguese', ro: 'Romanian',
- rs: 'Serbian', ru: 'Russian', se: 'Swedish', si: 'Slovene', sk: 'Slovak', tr: 'Turkish',
- tw: 'Chinese', ua: 'Ukranian', us: 'English', ve: 'Spanish', vn: 'Vietnamese', yu: 'Bosnian'
- }[code];
- // Look up if implemented contains the language.
- for(var i = 0; i < languageInfo.implemented.length; i++) {
- // If the language is implemented set the name to it and return.
- if(languageInfo.implemented[i] == languageName) {
- this.name = languageName;
- return;
- }
- }
- // If the language is not implemented, set the language to english.
- this.name = 'English';
- },
- /*
- * Set the text for the script.
- */
- setText: function() {
- // If a resource is used for the language text, use it.
- if(languageInfo.useResource) {
- // Get the ressource.
- var text = myGM.getResourceParsed('language' + this.name);
- // Store it to Language.text.
- this.text = (text && !text.is_error) ? text : languageInfo.defaultText;
- // Otherwise: Use the text in languageInfo.
- } else {
- // Get the text.
- var text = languageInfo['text'][this.name];
- // Store it to Language.text.
- this.text = (text && !text.is_error) ? text : languageInfo.text.English;
- }
- },
- /**
- * Return the name of the actually used language.
- *
- * @return String
- * The country code.
- */
- getLangName: function() {
- return this.name;
- },
- /**
- * Synonymous function for Language.getText().
- *
- * @param String name
- * The name of the placeholder.
- *
- * @return mixed
- * The text.
- */
- $: function(name) {
- return this.getText(name);
- },
- /**
- * Return the name of the actually used language.
- *
- * @param String name
- * The name of the placeholder.
- *
- * @return mixed
- * The text.
- */
- getText: function(name) {
- // Set the text to the placeholder.
- var erg = name;
- // Split the placeholder.
- var parts = name.split('_');
- // If the splitting was successful.
- if(parts) {
- // Set txt to the "next level".
- var txt = this.text ? this.text[parts[0]] : null;
- // Loop over all parts.
- for(var i = 1; i < parts.length; i++) {
- // If the "next level" exists, set txt to it.
- if(txt && typeof txt[parts[i]] != 'undefined') {
- txt = txt[parts[i]];
- } else {
- txt = erg;
- break;
- }
- }
- // If the text type is not an object, a function or undefined.
- if(typeof txt != 'object' && typeof txt != 'function' && typeof txt != 'undefined') {
- erg = txt;
- }
- }
- // Return the text.
- return erg;
- }
- };
- /********************************************************
- *********************************************************
- ***** *****
- ***** End of functions / variables for all Scripts. *****
- ***** *****
- *********************************************************
- ********************************************************/
- /**********************
- *** Ikariam Script. ***
- **********************/
- /**
- * Storage for the unsafeWindow.ikariam funtion.
- */
- var ika;
- /**
- * General functions.
- */
- General = {
- /**
- * Init the script.
- */
- init: function() {
- // Set the general used Script styles.
- this.setStyles();
- // Set unsafeWindow.ikariam to ika for easier access.
- ika = win.ikariam;
- // Get the id of the body.
- var viewId = document.body.id;
- // Get the name of the view depending on the body id.
- switch(viewId) {
- case 'worldmap_iso':
- View.name = 'world';
- break;
- case 'island':
- View.name = 'island';
- break;
- case 'city':
- View.name = 'town';
- break;
- default:
- break;
- }
- // Add the script toolbar.
- myGM.addElement('div', myGM.$('#GF_toolbar'), 'toolbar');
- },
- /**
- * Set the general script styles.
- */
- setStyles: function() {
- // Add the general used styles.
- myGM.addStyle(
- "#" + myGM.prefix + "toolbar { position: absolute; top: 0px; right: 0px; } \
- .bottomLine { border-bottom: 1px dotted #CCA569; } \
- .minimizeImg, .maximizeImg { background: url('skin/interface/window_control_sprite.png') no-repeat scroll 0 0 transparent; cursor: pointer; display: block; height: 18px; width: 18px; } \
- .minimizeImg { background-position: -144px 0; } \
- .minimizeImg:hover { background-position: -144px -19px; } \
- .maximizeImg { background-position: -126px 0; } \
- .maximizeImg:hover { background-position: -126px -19px; }"
- );
- // Set the notification style.
- myGM.addStyle(
- "." + myGM.prefix + "notificationBackground { z-index: 1000000000000; position: fixed; visibility: visible; top: 0px; left: 0px; width: 100%; height: 100%; padding: 0; background-color: #000; opacity: .7; } \
- ." + myGM.prefix + "notificationPanelContainer { z-index: 1000000000001; position: fixed; visibility: visible; top: 100px; left: 50%; width: 500px; height: 370px; margin-left: -250px; padding: 0; text-align: left; color: #542C0F; font: 12px Arial,Helvetica,sans-serif; } \
- ." + myGM.prefix + "notificationPanel { position: relative; top: 0px; left: 0px; background-color: transparent; border: 0 none; overflow: hidden; } \
- ." + myGM.prefix + "notificationPanelHeader { height: 39px; background: none repeat scroll 0 0 transparent; font-weight: bold; line-height: 2; white-space: nowrap; } \
- ." + myGM.prefix + "notificationPanelHeaderL { height: 39px; background-image: url('skin/layout/notes_top_left.png'); background-position: left top; background-repeat: no-repeat; } \
- ." + myGM.prefix + "notificationPanelHeaderR { height: 39px; background-image: url('skin/layout/notes_top_right.png'); background-position: right top; background-repeat: no-repeat; } \
- ." + myGM.prefix + "notificationPanelHeaderM { height: 39px; margin: 0 14px 0 38px; padding: 12px 0 0; background-image: url('skin/layout/notes_top.png'); background-position: left top; background-repeat: repeat-x; color: #811709; line-height: 1.34em; } \
- ." + myGM.prefix + "notificationPanelBody { max-height: 311px; height: 100%; background: none repeat scroll 0 0 transparent; } \
- ." + myGM.prefix + "notificationPanelBodyL { height: 100%; background-image: url('skin/layout/notes_left.png'); background-position: left top; background-repeat: repeat-y; } \
- ." + myGM.prefix + "notificationPanelBodyR { height: 100%; background-image: url('skin/layout/notes_right.png'); background-position: right top; background-repeat: repeat-y; } \
- ." + myGM.prefix + "notificationPanelBodyM { height: 100%; background-color: #F7E7C5; background-image: none; margin: 0 6px; padding: 0 10px; font-size: 14px; } \
- ." + myGM.prefix + "notificationPanelBodyMTop { max-height: 100px; line-height: 2; } \
- ." + myGM.prefix + "notificationPanelBodyMTop b { line-height: 3.5; font-size:110%; } \
- ." + myGM.prefix + "notificationPanelBodyM a { color: #811709; font-weight: bold; } \
- ." + myGM.prefix + "notificationPanelBodyM h2 { font-weight: bold; } \
- ." + myGM.prefix + "notificationPanelBodyMContent { max-height: 270px; padding: 10px; background: url('skin/input/textfield.png') repeat-x scroll 0 0 #FFF7E1; border: 1px dotted #C0C0C0; font: 14px Arial,Helvetica,sans-serif; color: #000000; border-collapse: separate; overflow-y:auto; } \
- ." + myGM.prefix + "notificationPanelBodyMBottom { max-height: 170px; padding: 10px; background: url('skin/input/textfield.png') repeat-x scroll 0 0 #FFF7E1; border: 1px dotted #C0C0C0; font: 14px Arial,Helvetica,sans-serif; color: #000000; border-collapse: separate; overflow-y:auto; } \
- ." + myGM.prefix + "notificationPanelBodyPlaceholder { height: 20px; } \
- ." + myGM.prefix + "notificationPanelFooter { height: 20px; background: none repeat scroll 0 0 transparent; } \
- ." + myGM.prefix + "notificationPanelFooterL { height: 100%; background-image: url('skin/layout/notes_left.png'); background-position: left top; background-repeat: repeat-y; border: 0 none; } \
- ." + myGM.prefix + "notificationPanelFooterR { height: 21px; background-image: url('skin/layout/notes_br.png'); background-position: right bottom; background-repeat: no-repeat; } \
- ." + myGM.prefix + "notificationPanelFooterM { background-color: #F7E7C5; border-bottom: 3px solid #D2A860; border-left: 2px solid #D2A860; margin: 0 23px 0 3px; padding: 3px 0 2px 3px; font-size: 77%; } \
- ." + myGM.prefix + "notificationPanelClose { cursor: pointer; position: absolute; top: 12px; right: 8px; width: 17px; height: 17px; background-image: url('skin/layout/notes_close.png'); } \
- ." + myGM.prefix + "notificationPanelButtonWrapper { bottom: -4px; position: absolute; margin: 10px auto; width: 100%; text-align: center; } \
- ." + myGM.prefix + "notificationPanelButton { background: url('skin/input/button.png') repeat-x scroll 0 0 #ECCF8E; border-color: #C9A584 #5D4C2F #5D4C2F #C9A584; border-style: double; border-width: 3px; cursor: pointer; display: inline; font-weight: bold; margin: 0px 5px; padding: 2px 10px; text-align: center; font-size: 12px; width: 100px; } \
- ." + myGM.prefix + "notificationPanelButton:hover { color: #B3713F; } \
- ." + myGM.prefix + "notificationPanelButton:active { border-color: #5D4C2F #C9A584 #C9A584 #5D4C2F; border-style: double; border-width: 3px; padding: 3px 10px 1px; } \
- ." + myGM.prefix + "notificationPanelButtonConfirm { } \
- ." + myGM.prefix + "notificationPanelButtonAbort { }",
- 'notification', true
- );
- // Set the updater style.
- myGM.addStyle(
- "." + myGM.prefix + "updateTable { border-collapse: separate; border-spacing: 2px; } \
- ." + myGM.prefix + "updateDataType { width: 100px; padding: 5px 0px 5px 5px; border: 1px solid #D2A860; } \
- ." + myGM.prefix + "updateDataInfo { width: 300px; padding: 5px 5px 5px 20px; border: 1px solid #D2A860; } \
- ." + myGM.prefix + "updateDataInfo ul li { list-style: disc outside none; }",
- 'updater', true
- );
- },
- /**
- * Parses a string number to an int value.
- *
- * @param String txt
- * The number to format.
- *
- * @return int
- * The formated value.
- */
- getInt: function(txt) {
- // Return the formated number.
- return parseInt(txt.replace(/(\.|,)/g, ''));
- },
- /**
- * Returns the value of the selected option of a select field.
- *
- * @param String id
- * The last part of the id of the element.
- * @param boolean hasNoPrefix
- * Says if the id has no prefix.
- *
- * @return String
- * The value.
- */
- getSelectValue: function(id, hasNoPrefix) {
- // Get the select field.
- var select = myGM.$('#' + (hasNoPrefix ? '' : myGM.prefix) + id);
- // Return the value.
- return select.options[select.selectedIndex].value;
- },
- /**
- * Returns a code consisting of the server name and the country code.
- *
- * @return string
- * The code.
- */
- getServerCode: function() {
- // Split the host string.
- var lang = top.location.host.split('.');
- // Set the language name.
- return (lang ? lang[1] + '_' + lang[0] : 'undefined');
- },
- /**
- * Formats a number to that format that is used in Ikariam.
- *
- * @param int num
- * The number to format.
- * @param boolean || boolean[] addColor
- * If the number should be coloured. (optional, if not set, a color will be used for negative and no color will be used for positive numbers)
- *
- * @return String
- * The formated number.
- */
- formatToIkaNumber: function(num, addColor, usePlusSign) {
- var txt = num + '';
- // Set a seperator every 3 digits from the end.
- txt = txt.replace(/(\d)(?=(\d{3})+\b)/g, '$1' + Language.$('settings_kiloSep'));
- // If the number is negative and it is enabled, write it in red.
- if(num < 0 && !(addColor == false || (addColor && addColor.negative == false))) {
- txt = '<span class="red bold negative">' + txt + '</span>';
- }
- // If the number is positive.
- if(num > 0) {
- // Add the plus sign if wanted.
- txt = (usePlusSign ? '+' : '') + txt;
- // Color the text green if wanted.
- if(!!(addColor == true || (addColor && addColor.positive == true))) {
- txt = '<span class="green bold">' + txt + '</span>';
- }
- }
- // Return the formated number.
- return txt;
- },
- /**
- * Shows a hint to the user.
- *
- * @param String located
- * The location of the hint. Possible are all advisors, a clicked element or a committed element.
- * @param String type
- * The type of the hint. Possible is confirm, error, neutral or follow the mouse.
- * @param String msgText
- * The hint text.
- * @param String msgBindTo
- * An element the tooltip is binded (only used if located = committedElement).
- * @param String msgIsMinSize
- * If the message is minimized (only used if type = followMouse).
- */
- showTooltip: function(located, type, msgText, msgBindTo, msgIsMinSize) {
- // Get the message location.
- var msgLocation = -1;
- switch(located) {
- case 'cityAdvisor':
- msgLocation = 1;
- break;
- case 'militaryAdvisor':
- msgLocation = 2;
- break;
- case 'researchAdvisor':
- msgLocation = 3;
- break;
- case 'diplomacyAdvisor':
- msgLocation = 4;
- break;
- case 'clickedElement':
- msgLocation = 5;
- break;
- case 'committedElement':
- msgLocation = 6;
- break;
- }
- // Get the message type.
- var msgType = -1;
- switch(type) {
- case 'confirm':
- msgType = 10;
- break;
- case 'error':
- msgType = 11;
- break;
- case 'neutral':
- msgType = 12;
- break;
- case 'followMouse':
- msgType = 13;
- break;
- }
- // Show the tooltip.
- ika.controller.tooltipController.bindBubbleTip(msgLocation, msgType, msgText, null, msgBindTo, msgIsMinSize);
- },
- /**
- * Toogle the show / hide Button image and title.
- *
- * @param Element button
- * The button to toggle.
- */
- toggleShowHideButton: function(button) {
- // Switch the button picture.
- button.classList.toggle('minimizeImg');
- button.classList.toggle('maximizeImg');
- // Switch the button title.
- if(button.title == Language.$('general_hide')) {
- button.title = Language.$('general_show');
- } else {
- button.title = Language.$('general_hide');
- }
- }
- };
- /**
- * Functions for event handling.
- */
- EventHandling = {
- /**
- * Events for the upkeep reduction tables.
- */
- upkeepReductionTable: {
- /**
- * Toggles the visibility of the reduction information rows.
- */
- toggle: function(e) {
- // Toggle the button.
- General.toggleShowHideButton(this);
- // Get the table rows.
- var tr = myGM.$$('tr', this.parentNode.parentNode.parentNode);
- // Toggle the visibility of all table rows except the first.
- for(var i = 1; i < tr.length; i++) {
- tr[i].classList.toggle('invisible');
- }
- // Adjust the size of the Scrollbar.
- ika.controller.adjustSizes();
- }
- },
- /**
- * Events for the zoom function.
- */
- zoomFunction: {
- /**
- * Zoom in when clicking on the zoom in button.
- */
- zoomIn: function() {
- // Get the zoom factor.
- var factor = myGM.getValue('zoom_' + View.name + 'Factor', 100) + ZoomFunction.zoomStep;
- // Zoom.
- ZoomFunction.zoom(factor);
- },
- /**
- * Zoom out when clicking on the zoom out button.
- */
- zoomOut: function() {
- // Get the zoom factor.
- var factor = myGM.getValue('zoom_' + View.name + 'Factor', 100) - ZoomFunction.zoomStep;
- // Zoom.
- ZoomFunction.zoom(factor);
- },
- /**
- * Zoom if the mouse is scrolled.
- */
- mouseScroll: function(e) {
- // Check if the required keys are pressed.
- var keysPressed = myGM.getValue('zoom_ctrlPressed', true) ? !!e.ctrlKey : true
- && myGM.getValue('zoom_altPressed', false) ? !!e.altKey : true
- && myGM.getValue('zoom_shiftPressed', false) ? !!e.shiftKey : true;
- // If the required keys are pressed.
- if(keysPressed) {
- // If the scrolling is horizontally return.
- if (e.axis !== undefined && e.axis === e.HORIZONTAL_AXIS) {
- return;
- }
- // Strorage for the number of steps to scroll.
- var stepNumber = 0;
- // Get the number of steps to scroll.
- if (e.wheelDelta) {
- stepNumber = e.wheelDelta / 120;
- }
- if (e.detail) {
- stepNumber = -e.detail / 3;
- }
- if (e.wheelDeltaY !== undefined) {
- stepNumber = e.wheelDeltaY / 120;
- }
- // If the number is between -1 and 0, set it to -1.
- if(stepNumber < 0) {
- stepNumber = stepNumber > -1 ? -1 : Math.round(stepNumber);
- // If the number is between 0 and 1, set it to 1.
- } else {
- stepNumber = stepNumber < 1 ? 1 : Math.round(stepNumber);
- }
- // Get the zoom factor.
- var factor = myGM.getValue('zoom_' + View.name + 'Factor', 100) + ZoomFunction.zoomStep * stepNumber;
- // Zoom the view.
- ZoomFunction.zoom(factor);
- // Stop the default event.
- if(e.preventDefault) {
- e.preventDefault();
- } else {
- return false;
- }
- }
- }
- },
- /**
- * Events for the option panel.
- */
- optionPanel: {
- /**
- * Toggles the visibility of the option wrapper contents.
- */
- toggle: function(e) {
- // Toggle the button.
- General.toggleShowHideButton(this);
- // Toggle the visibility of the content.
- myGM.$('.content', this.parentNode.parentNode).classList.toggle('invisible');
- // Store the visibility.
- var optionId = this.parentNode.parentNode.id.replace(myGM.prefix, '');
- OptionPanel.optionVisibility[optionId] = !OptionPanel.optionVisibility[optionId];
- myGM.setValue('optionPanel_optionVisibility', OptionPanel.optionVisibility);
- // Adjust the size of the Scrollbar.
- ika.controller.adjustSizes();
- },
- /**
- * Save the settings in the option panel.
- */
- saveSettings: function() {
- OptionPanel.saveSettings();
- }
- },
- /**
- * Events for the info link.
- */
- memberInfo: {
- /**
- * Is called after the info link is clicked.
- */
- clickShow: function() {
- // Set the flag showing the link was klicked.
- myGM.setValue('memberInfo_infoLinkClicked', true);
- // Set the search settings so that the needed view is shown.
- myGM.$('#tab_highscore input[name="searchUser"]').value = '';
- myGM.$('#searchOnlyFriends').checked = false;
- myGM.$('#searchOnlyAllies').checked = true;
- // Start the search.
- myGM.$('#tab_highscore input[type="submit"]').click();
- },
- /**
- * Is called after the reset button is clicked.
- */
- clickReset: function() {
- // Store the member information and the actual time.
- myGM.setValue(General.getServerCode() + '_memberInfo_data_' + MemberInfo.type, MemberInfo.data);
- myGM.setValue(General.getServerCode() + '_memberInfo_time_' + MemberInfo.type, (new Date).getTime());
- // Update the view.
- EventHandling.memberInfo.clickShow();
- }
- },
- /**
- * Events for missing resources.
- */
- missingResources: {
- /**
- * If the resources are updated.
- */
- resourcesUpdated: function(e) {
- // If the popup is closed, remove the action listener.
- if(!myGM.$('#buildingUpgrade')) {
- myGM.$('#cityResources').removeEventListener('DOMSubtreeModified', EventHandling.missingResources.resourcesUpdated, false);
- // Otherwise: update the resources if necessary.
- } else {
- // Timeout to have access to GM_ funtions.
- setTimeout(function() { MissingResources.show(true, true); }, 0);
- }
- }
- },
- /**
- * Functions for replaced urls.
- */
- replacedUrl: {
- /**
- * Is called after a replaced url is clicked.
- */
- click: function(e) {
- // The link which should be opened.
- var linkToOpen = this.innerHTML.decodeHTML();
- // Set the notification text.
- var notificationText = {
- header: Language.$('replacedUrl_notification_header'),
- body: Language.$('replacedUrl_notification_text1') + '<span class="bold red">"' + linkToOpen + '"</span>' + Language.$('replacedUrl_notification_text2'),
- confirm: Language.$('general_yes'),
- abort: Language.$('general_no')
- };
- // Set the notification callback.
- var notificationCallback = {
- confirm: function() { win.open(linkToOpen); }
- };
- // Show the notification.
- myGM.notification(notificationText, notificationCallback);
- }
- },
- /**
- * Functions for unit info.
- */
- unitInfo: {
- /**
- * Is called after the "show info" button is clicked.
- */
- click: function() {
- UnitInfo.showPopup();
- }
- },
- /**
- * Events for loading preview.
- */
- loadingPreview: {
- /**
- * Is called after an attribute of loadingPreview was modified.
- *
- * @param event e
- * The calling event.
- */
- attrModified: function(e) {
- // If the attribute was changed.
- if(e.attrChange == MutationEvent.MODIFICATION) {
- // If the style.display is set to none.
- if(e.attrName.trim() == 'style' && e.newValue.search(/display: none/i) != -1) {
- // Timeout to have access to GM_ funtions.
- setTimeout(EnhancedView.getPopup, 0);
- }
- }
- }
- }
- };
- /**
- * Functions for enhanced view.
- */
- EnhancedView = {
- /**
- * Inits the enhanced view.
- * Adds the event listener to the loadingPreview.
- */
- init: function() {
- // Wait for a popup.
- myGM.$('#loadingPreview').addEventListener('DOMAttrModified', EventHandling.loadingPreview.attrModified, false);
- // Init parts which are not shown in popups.
- this.initStatic();
- },
- /**
- * Inits the modifications on the website which are not shown in popups.
- */
- initStatic: function() {
- // Hide the Bird animation.
- if(myGM.getValue('module_hideBirdsActive', true)) View.hideBirds();
- // Init the Zoom function.
- if(myGM.getValue('module_zoomActive', true)) ZoomFunction.init();
- // Init the circular message link.
- if(myGM.getValue('module_easyCircularMsgActive', true)) Message.easyCircularMessage();
- // Init the function for showing the resource information.
- if(myGM.getValue('module_resourceInfoActive', true)
- || myGM.getValue('module_capacityInfoActive', true)) ResourceInfo.init();
- // Move loading circle.
- if(myGM.getValue('module_lcMoveActive', true)) View.moveLoadingCircle();
- // Init the function for showing the missing resources.
- if(myGM.getValue('module_missingResActive', true)) MissingResources.init();
- // Init the function for easy access of some popups.
- if(myGM.getValue('module_easyAccessActive', true)) ResourceInfo.addRessourceLinks();
- // Don't center town advisor.
- if(myGM.getValue('module_nctAdvisorActive', true)) View.noCenterTownAdvisor();
- // If the military tooltip should be shown without mouseover or click, add the styles.
- if(myGM.getValue('module_directMilitaryTtActive', true)) Tooltips.initDirectMilitaryTooltip();
- // Set the colonizing links.
- if(myGM.getValue('module_colonizingLinksActive', true)
- && View.name == 'island') City.setColonizingLinks();
- // Set the styles for the
- if(myGM.getValue('module_replaceUrlsActive', true)) Message.setStyleForReplaceUrl();
- // Init the function for showing the missing resources.
- if(myGM.getValue('module_memberInfoActive', false)) MemberInfo.init();
- },
- /**
- * Calls the script module depending on the popup.
- */
- getPopup: function() {
- // Update resource information.
- if(myGM.getValue('module_resourceInfoActive', true)) ResourceInfo.updateHourlyResourceInfo();
- // Set the colonizing links.
- if(myGM.getValue('module_colonizingLinksActive', true) && View.name == 'island') City.setColonizingLinks();
- // If the script was already executed on this popup.
- if(myGM.$('#' + myGM.prefix + 'alreadyExecutedPopup')) return;
- // Get the popup.
- var popup = myGM.$('.templateView');
- // Get the popup id.
- var popupId = popup ? popup.id.replace('_c', '') : '';
- // If a popup exists, add the hint, that the popup script was executed.
- if(popup) {
- var alreadyExecuted = myGM.addElement('input', myGM.$('.mainContent', popup), 'alreadyExecutedPopup');
- alreadyExecuted.type = 'hidden';
- }
- /******************************************************
- *** Functions that should only run once on a popup. ***
- ******************************************************/
- // Select the modules of the script which should be executed.
- switch(popupId) {
- // Options popup.
- case 'options':
- OptionPanel.show();
- break;
- // Finance popup.
- case 'finances':
- if(myGM.getValue('module_incomeActive', true)) Balance.incomeOnTop();
- if(myGM.getValue('module_urtShortActive', true)) Balance.shortUpkeepReductionTable();
- break;
- // Military view popup.
- case 'militaryAdvisor':
- if(myGM.getValue('module_directMilitaryTtActive', true)) Tooltips.directMilitaryTooltip();
- if(myGM.getValue('module_ttAutoActive', true)) Tooltips.autoshowInMilitaryView();
- break;
- // Diplomacy ally view popup.
- case 'diplomacyAlly':
- if(myGM.getValue('module_ttAutoActive', true)) Tooltips.autoshowInAllianceView();
- break;
- // Show messages.
- case 'diplomacyAdvisor':
- case 'diplomacyAdvisorOutBox':
- case 'diplomacyAdvisorArchive':
- case 'diplomacyAdvisorArchiveOutBox':
- if(myGM.getValue('module_replaceUrlsActive', true)) Message.replaceUrl();
- break;
- // Diplomacy ally view popup in embassy.
- case 'embassy':
- if(myGM.getValue('module_ttAutoActive', true)) Tooltips.autoshowInAllianceView();
- break;
- // Building ground popup.
- case 'buildingGround':
- if(myGM.getValue('module_missingResActive', true)) MissingResources.showInBuildingGround();
- break;
- // Write message popup.
- case 'sendIKMessage':
- if(myGM.getValue('module_messageSigActive', true)) Message.addSignature();
- break;
- // Troops in town popup.
- case 'cityMilitary':
- if(myGM.getValue('module_unitInfoActive', true)) UnitInfo.addPopupLink();
- break;
- // Highscore popup.
- case 'highscore':
- if(myGM.getValue('module_memberInfoActive', false)) MemberInfo.show();
- break;
- }
- // Building view.
- if(myGM.$('#buildingUpgrade') && myGM.getValue('module_missingResActive', true)) MissingResources.showInSidebar();
- }
- };
- /**
- * Functions for the general view.
- */
- View = {
- /**
- * Storage for the name of the view.
- */
- name: '',
- /**
- * Move loading circle to breadcrumb.
- */
- moveLoadingCircle: function() {
- // Add the styles.
- myGM.addStyle(
- "#js_worldBread { margin-left: 16px !important; } \
- #loadingPreview { transform: scale(0.5); -o-transform: scale(0.5); -webkit-transform: scale(0.5); left: 35px !important; top: 141px !important; }"
- );
- },
- /**
- * Hide the bird animation but no other animation.
- */
- hideBirds: function() {
- // Add the style.
- myGM.addStyle(
- ".bird_swarm { visibility: hidden !important; }"
- );
- },
- /**
- * Don't center the city and date in town advisor vertically.
- */
- noCenterTownAdvisor: function() {
- // Add the style.
- myGM.addStyle(
- "#inboxCity td { vertical-align: top !important; }"
- );
- }
- };
- /**
- * Functions for tooltips.
- */
- Tooltips = {
- /**
- * Show tooltips in alliance view automatically.
- */
- autoshowInAllianceView: function() {
- // Enable toggling on mouseover / mouseout.
- this.autoshowGeneral('cityInfo');
- },
- /**
- * Show tooltips in military advisor view automatically.
- */
- autoshowInMilitaryView: function() {
- // Enable toggling on mouseover / mouseout.
- this.autoshowGeneral('spyMilitary', myGM.getValue('module_directMilitaryTtActive', true));
- },
- /**
- * Show tooltips with class name magnifierClass automatically.
- *
- * @param String magnifierClass
- * The class of the tooltips to enable toggling.
- * @param boolean deleteOnClick
- * If the onClick event should be deleted or just moved to mouseover.
- */
- autoshowGeneral: function(magnifierClass, deleteOnClick) {
- // Get all magnifiers.
- var magnifier = myGM.$$('.' + magnifierClass);
- // Set the mousover and mouseout for all magnifiers.
- for(var i = 0; i < magnifier.length; i++) {
- // Get the onclick event and "delete" the old one.
- var magOnClick = magnifier[i].onclick;
- magnifier[i].onclick = 'return false;';
- // If the on click event should be moved.
- if(!deleteOnClick) {
- // Add the show event.
- var magIcon = myGM.$('.magnify_icon', magnifier[i]);
- if(!magIcon) magIcon = magnifier[i];
- magIcon.addEventListener('mouseover', function(e) { ika.controller.captureMousePosition(e); this(e); }.bind(magOnClick), true);
- }
- }
- // If the on click event should be moved.
- if(!deleteOnClick) {
- // Trigger the close event with jQuery on a click on the popup.
- myGM.$('.templateView .mainContent').addEventListener('click', function() { win.$(document).trigger("closeExclusiveInfo"); }, true);
- }
- },
- /**
- * Shows the military tooltip without mouseover.
- */
- initDirectMilitaryTooltip: function() {
- // Add the styles.
- myGM.addStyle(
- "#js_MilitaryMovementsFleetMovementsTable .military_event_table .magnify_icon { background-image: none; cursor: default; width: 240px; } \
- #js_MilitaryMovementsFleetMovementsTable .military_event_table .magnify_icon .infoTip { display: inline; position: relative; padding: 0px; border: none; } \
- #js_MilitaryMovementsFleetMovementsTable .military_event_table .magnify_icon .infoTip h5 { display: none; } \
- #js_MilitaryMovementsFleetMovementsTable .military_event_table .icon40 { background-size: 25px 25px; background-color: transparent; padding: 26px 3px 0px 3px; width: 30px; } \
- #js_MilitaryMovementsFleetMovementsTable .military_event_table .icon40.resource_icon { background-size: 20px 16px; }"
- );
- },
- /**
- * Hide the ship number of own transports and add titles to the loaded troops / ships / resources.
- */
- directMilitaryTooltip: function() {
- // Get the table rows.
- var militaryEventTableTr = myGM.$$('#js_MilitaryMovementsFleetMovementsTable .military_event_table tr');
- // Loop at the table rows.
- for(var i = 1; i < militaryEventTableTr.length; i++) {
- // Get the mission div.
- var missionDiv = myGM.$('td:nth-child(1) div.mission_icon', militaryEventTableTr[i]);
- // If it is your own table row and the mission is transport or trade.
- if(militaryEventTableTr[i].classList.contains('own') && (missionDiv.classList.contains('transport') || missionDiv.classList.contains('trade'))) {
- // Hide the table cell.
- myGM.$('td:nth-child(4) div', militaryEventTableTr[i]).classList.add('invisible');
- }
- }
- // Storage for the unit / ships / resources classes and names.
- var idTranslation = new Array(
- { classId: 'swordsman', langId: 'name_unit_swordsman' }, { classId: 'phalanx', langId: 'name_unit_phalanx' }, { classId: 'archer', langId: 'name_unit_archer' }, { classId: 'marksman', langId: 'name_unit_marksman' }, { classId: 'mortar', langId: 'name_unit_mortar' }, { classId: 'slinger', langId: 'name_unit_slinger' }, { classId: 'catapult', langId: 'name_unit_catapult' }, { classId: 'ram', langId: 'name_unit_ram' }, { classId: 'steamgiant', langId: 'name_unit_steamgiant' }, { classId: 'bombardier', langId: 'name_unit_bombardier' }, { classId: 'cook', langId: 'name_unit_cook' },
- { classId: 'medic', langId: 'name_unit_medic' }, { classId: 'gyrocopter', langId: 'name_unit_gyrocopter' }, { classId: 'spearman', langId: 'name_unit_spearman' }, { classId: 'ship_balliasta', langId: 'name_ship_balliasta' }, { classId: 'ship_catapult', langId: 'name_ship_catapult' }, { classId: 'ship_flamethrower', langId: 'name_ship_flamethrower' }, { classId: 'ship_mortar', langId: 'name_ship_mortar' }, { classId: 'ship_ram', langId: 'name_ship_ram' }, { classId: 'ship_steamboat', langId: 'name_ship_steamboat' }, { classId: 'ship_rocketship', langId: 'name_ship_rocketship' }, { classId: 'ship_submarine', langId: 'name_ship_submarine' },
- { classId: 'ship_paddlespeedship', langId: 'name_ship_paddlespeedship' }, { classId: 'ship_balloncarrier', langId: 'name_ship_balloncarrier' }, { classId: 'ship_tender', langId: 'name_ship_tender' }, { classId: 'ship_transport', langId: 'name_ship_transport' }, { classId: 'ship_premium_transport', langId: 'name_ship_transport' }, { classId: 'gold', langId: 'name_resource_gold' }, { classId: 'wood', langId: 'name_resource_wood' }, { classId: 'wine', langId: 'name_resource_wine' }, { classId: 'marble', langId: 'name_resource_marble' }, { classId: 'glass', langId: 'name_resource_glass' }, { classId: 'sulfur', langId: 'name_resource_sulfur' }
- );
- // Get the event table.
- var movementsTable = myGM.$('#js_MilitaryMovementsFleetMovementsTable');
- // Add the unit names.
- for(var i = 0; i < idTranslation.length; i++) {
- var detailIcon = myGM.$$('.icon40.' + idTranslation[i].classId, movementsTable);
- for(var k = 0; k < detailIcon.length; k++) {
- detailIcon[k].title = Language.$(idTranslation[i].langId);
- }
- }
- }
- };
- /**
- * Functions for balance view.
- */
- Balance = {
- /**
- * Shows the actual income also on top of the site.
- */
- incomeOnTop: function() {
- // Get the table for the summary.
- var summaryTable = myGM.$('.table01');
- // Show the income on top.
- this.showIncomeOnTop(summaryTable);
- // Adjust the size of the Scrollbar.
- ika.controller.adjustSizes();
- },
- /**
- * Show the actual income on top of the site.
- *
- * @param element summaryTable
- * The table for the summary.
- */
- showIncomeOnTop: function(summaryTable) {
- // Get the actual income.
- var income = this.getIncome();
- // Create the rows for the income per day and the income per day.
- var incomeRow = myGM.addElement('tr', summaryTable, null, new Array('result', 'alt'));
- var incomeRow24h = myGM.addElement('tr', summaryTable, null, 'result');
- // Create the content of the table rows.
- this.createTableRow(new Array(Language.$('balance_income_perHour'), '', '', General.formatToIkaNumber(income)), new Array('sigma', ['value', 'res'], ['value', 'res'], ['value', 'res']), incomeRow, false);
- this.createTableRow(new Array(Language.$('balance_income_perDay'), '', '', General.formatToIkaNumber(income * 24)), new Array('sigma', ['value', 'res'], ['value', 'res'], ['value', 'res']), incomeRow24h, false);
- },
- /**
- * Gets the actual income from the Ikariam page and returns it.
- *
- * @return int
- * The actual income
- */
- getIncome: function() {
- // Get the table cell with the actual income.
- var incomeCell = myGM.$$('.hidden')[myGM.$$('.hidden').length - 1];
- // If the content of the cell is not just the income move one element inwards.
- while(incomeCell.firstChild.firstChild) {
- incomeCell = incomeCell.firstChild;
- }
- // Get the actual income.
- var txt = incomeCell.innerHTML;
- // Remove the thousand seperators.
- return General.getInt(txt);
- },
- /**
- * Shows a short upkeep reduction table.
- */
- shortUpkeepReductionTable: function() {
- // Get the upkeep redutcion tables.
- var uRT = myGM.$$('.upkeepReductionTable');
- if(uRT.length == 0) {
- uRT = myGM.$$('#upkeepReductionTable');
- }
- // Create an array for data storage.
- var row = {
- reason: new Array(),
- basicUpkeep: new Array(),
- supplyUpkeep: new Array(),
- result: new Array()
- };
- // Get the data for the troops and ships redution rows.
- for(var i = 0; i < 3; i++) {
- row.reason.push(Language.$('balance_upkeep_reason_' + i));
- row.basicUpkeep.push(General.getInt(myGM.$$('.altbottomLine td.hidden, .result td.hidden, .alt.bottomLine td.hidden, .result td.hidden', uRT[0])[i].innerHTML));
- row.supplyUpkeep.push(General.getInt(myGM.$$('.altbottomLine td.hidden, .result td.hidden, .alt.bottomLine td.hidden, .result td.hidden', uRT[1])[i].innerHTML));
- row.result.push(row.basicUpkeep[i] + row.supplyUpkeep[i]);
- }
- // Get the start income.
- var beforeReduction = General.getInt(myGM.$('td.hidden', uRT[2]).innerHTML);
- // Get the result income.
- var income = this.getIncome();
- // Create the table to show the
- var shortTable = myGM.addElement('table', uRT[0].parentNode, null, new Array('table01', 'border', 'left'), null, null, uRT[0]);
- shortTable.id = 'balance';
- // Create the table head.
- this.createTableRow(new Array('', Language.$('balance_upkeep_basic'), Language.$('balance_upkeep_supply'), Language.$('balance_upkeep_result')), new Array('city', ['value', 'res'], ['value', 'res'], ['value', 'res']), myGM.addElement('tr', shortTable), true);
- // Create the start income row.
- var startRow = myGM.addElement('tr', shortTable, null, new Array('alt', 'bottomLine'));
- this.createTableRow(new Array(Language.$('balance_income_start'), '', '', General.formatToIkaNumber(beforeReduction)), new Array('city', ['value', 'res'], ['value', 'res'], ['value', 'res']), startRow, false);
- // Create the troops / ships redution rows.
- for(var i = 0; i < 3; i++) {
- var newRow = myGM.addElement('tr', shortTable, null, (i % 2 == 1) ? new Array('alt', 'bottomLine') : '');
- this.createTableRow(new Array(row.reason[i], General.formatToIkaNumber(-row.basicUpkeep[i]), General.formatToIkaNumber(-row.supplyUpkeep[i]), General.formatToIkaNumber(-row.result[i])), new Array('city', ['value', 'res'], ['value', 'res'], 'hidden'), newRow, false);
- }
- // Create the result row.
- var resultRow = myGM.addElement('tr', shortTable, null, 'result');
- this.createTableRow(new Array('<img alt="Summe" src="skin/layout/sigma.png">', '', '', General.formatToIkaNumber(income)), new Array('sigma', ['value', 'res'], ['value', 'res'], 'hidden'), resultRow, false);
- // Create the spacing between the tables.
- myGM.addElement('hr', uRT[0].parentNode, null, null, null, null, uRT[0]);
- // Hide the data rows of the tables and add the show button.
- for(var i = 0; i < uRT.length; i++) {
- // Get all rows.
- var tr = myGM.$$('tr', uRT[i]);
- // Hide all rows except the first.
- for(var k = 1; k < tr.length; k++) {
- tr[k].classList.add('invisible');
- }
- // Add the show button to the first row.
- var th = myGM.$('th', tr[0]);
- var btn = myGM.addElement('div', th, null, 'maximizeImg', new Array(['cssFloat', 'left']), th.firstChild);
- btn.title = Language.$('general_show');
- // Add the event listener.
- btn.addEventListener('click', EventHandling.upkeepReductionTable.toggle, false);
- }
- // Adjust the size of the Scrollbar.
- ika.controller.adjustSizes();
- },
- /**
- * Adds cells to a table row.
- *
- * @param String[] cellText
- * Array with the text of the cells.
- * @param String[] cellClassName
- * Array with the classes of the cells.
- * @param element row
- * Table row where the cells should be added.
- * @param boolean head
- * If the row is a table head row.
- */
- createTableRow: function(cellText, cellClassName, row, head) {
- // Do this for every cell.
- for(var i = 0; i < cellText.length; i++) {
- // Add the cell.
- var cell = myGM.addElement(head ? 'th' : 'td', row, null, cellClassName[i]);
- // Set the content of the cell.
- cell.innerHTML = cellText[i];
- }
- }
- };
- /**
- * Functions for option panel.
- */
- OptionPanel = {
- /**
- * Storage for option visibility.
- */
- optionVisibility: {
- moduleOption: true
- },
- /**
- * Adds the tab for the script options.
- */
- show: function() {
- // Get the script options tab.
- var tabGMOptions = myGM.$('#tabScriptOptions');
- // If the script options tab doesn't exists, create it.
- if(!tabGMOptions) {
- // Set the styles.
- this.setStyles();
- // Add the GM tab link to the tab menu.
- var tabmenu = myGM.$('.tabmenu');
- var jsTabGMOptions = myGM.addElement('li', tabmenu, 'js_tabScriptOptions', 'tab', null, false);
- jsTabGMOptions.innerHTML = '<b class="tabScriptOptions"> ' + Language.$('optionPanel_scripts') + ' </b>';
- jsTabGMOptions.setAttribute('onclick', "switchTab('tabScriptOptions');");
- // Add the content wrapper for the GM tab to the tab menu.
- var mainContent = myGM.$('#tabGameOptions').parentNode;
- tabGMOptions = myGM.addElement('div', mainContent, 'tabScriptOptions', null, new Array(['display', 'none']), false);
- }
- // Fill the tab with content.
- this.createTabContent(tabGMOptions);
- },
- /**
- * Sets the styles that are used for the update-panel.
- */
- setStyles: function() {
- // Add all styles to the ikariam page.
- myGM.addStyle(
- "#js_tabGameOptions, #js_tabAccountOptions, #js_tabFacebookOptions, #js_tabOpenIDOptions, #js_tabScriptOptions { width: 130px !important; margin-left: 5px !important; border-radius: 5px 5px 0px 0px } \
- ." + myGM.prefix + "SignatureInput { resize: none; width: 99%; height: 75px; } \
- #tabScriptOptions hr { margin: 0; } \
- .cbWrapper { margin: 0 0 0 10px; }"
- );
- },
- /**
- * Creates the content of the tab.
- *
- * @param element tab
- * The tab where the content should be added.
- */
- createTabContent: function(tab) {
- // Get the option visibility.
- this.optionVisibility = myGM.getValue('optionPanel_optionVisibility', this.optionVisibility);
- // Create the wrapper for the enabling / disabling of modules.
- var moduleContentWrapper = this.createOptionsWrapper(tab, Language.$('optionPanel_section_module_title'), 'moduleOption');
- this.createModuleContent(moduleContentWrapper);
- // Create the wrapper for the update settings.
- var updateContentWrapper = this.createOptionsWrapper(tab, Language.$('optionPanel_section_update_title'), 'updateOption');
- this.createUpdateContent(updateContentWrapper);
- // Create the wrapper for the resource information / missing resources.
- var rimrContentWrapper = this.createOptionsWrapper(tab, Language.$('optionPanel_section_resInfoMissingRes_title'), 'resInfoMissingResOption');
- this.createResInfoMissingResContent(rimrContentWrapper);
- // Create the wrapper for the zoom settings.
- var zoomContentWrapper = this.createOptionsWrapper(tab, Language.$('optionPanel_section_zoom_title'), 'zoomOption');
- this.createZoomContent(zoomContentWrapper);
- // Create the wrapper for the zoom settings.
- var sigContentWrapper = this.createOptionsWrapper(tab, Language.$('optionPanel_section_messageSignature_title'), 'messageSignatureOption');
- this.createMessageSigContent(sigContentWrapper);
- },
- /**
- * Create a wrapper for a section on the option panel.
- *
- * @param element tab
- * The tab where the wrapper should be added.
- * @param String headerText
- * The text of the header.
- * @param String id
- * The id of the option wrapper.
- *
- * @return element
- * The wrapper for the content of the options.
- */
- createOptionsWrapper: function(tab, headerText, id) {
- // Get the content show status.
- var showContent = !!this.optionVisibility[id];
- // Create the wrapper.
- var optionsWrapper = myGM.addElement('div', tab, id, 'contentBox01h');
- // Create the header.
- var optionsHeader = myGM.addElement('h3', optionsWrapper, null, 'header');
- optionsHeader.innerHTML = headerText;
- // Add the show / hide button.
- var btn = myGM.addElement('div', optionsHeader, null, showContent ? 'minimizeImg' : 'maximizeImg', new Array(['cssFloat', 'left']));
- btn.addEventListener('click', EventHandling.optionPanel.toggle, false);
- btn.title = showContent ? Language.$('general_hide') : Language.$('general_show');
- // Create the content wrapper.
- var optionsWrapperContent = myGM.addElement('div', optionsWrapper, null, showContent ? 'content' : new Array('content', 'invisible'));
- // Create the footer.
- myGM.addElement('div', optionsWrapper, null, 'footer');
- // Return the content wrapper.
- return optionsWrapperContent;
- },
- /**
- * Creates the content of the module part.
- *
- * @param element contentWrapper
- * The wrapper where the content should be added.
- */
- createModuleContent: function(contentWrapper) {
- // Create options table.
- var updateTable = this.addOptionsTable(contentWrapper);
- // Set the checkbox data.
- var cbData = new Array(
- { id: 'update', checked: myGM.getValue('module_updateActive', true), label: Language.$('optionPanel_section_module_label_updateActive'), hrAfter: true },
- { id: 'incomeOnTop', checked: myGM.getValue('module_incomeActive', true), label: Language.$('optionPanel_section_module_label_incomeOnTopActive'), hrAfter: false },
- { id: 'upkeepReduction', checked: myGM.getValue('module_urtShortActive', true), label: Language.$('optionPanel_section_module_label_upkeepReductionActive'), hrAfter: false },
- { id: 'missingResources', checked: myGM.getValue('module_missingResActive', true), label: Language.$('optionPanel_section_module_label_missingResActive'), hrAfter: false },
- { id: 'resourceInformation', checked: myGM.getValue('module_resourceInfoActive', true), label: Language.$('optionPanel_section_module_label_resourceInfoActive'), hrAfter: false },
- { id: 'capacityInformation', checked: myGM.getValue('module_capacityInfoActive', true), label: Language.$('optionPanel_section_module_label_capacityInfoActive'), hrAfter: false },
- { id: 'easyAccess', checked: myGM.getValue('module_easyAccessActive', true), label: Language.$('optionPanel_section_module_label_easyAccessActive'), hrAfter: false },
- { id: 'zoom', checked: myGM.getValue('module_zoomActive', true), label: Language.$('optionPanel_section_module_label_zoomActive'), hrAfter: true },
- { id: 'messageSignature', checked: myGM.getValue('module_messageSigActive', true), label: Language.$('optionPanel_section_module_label_messageSignatureActive'), hrAfter: false },
- { id: 'easyCircularMessage', checked: myGM.getValue('module_easyCircularMsgActive', true), label: Language.$('optionPanel_section_module_label_easyCircularMsgActive'), hrAfter: false },
- { id: 'replaceUrls', checked: myGM.getValue('module_replaceUrlsActive', true), label: Language.$('optionPanel_section_module_label_replaceUrlsActive'), hrAfter: false },
- { id: 'colonizingLinks', checked: myGM.getValue('module_colonizingLinksActive', true), label: Language.$('optionPanel_section_module_label_colonizingLinksActive'), hrAfter: true },
- { id: 'loadingCircleMove', checked: myGM.getValue('module_lcMoveActive', true), label: Language.$('optionPanel_section_module_label_lcMoveActive'), hrAfter: false },
- { id: 'tooltipsAuto', checked: myGM.getValue('module_ttAutoActive', true), label: Language.$('optionPanel_section_module_label_tooltipsAutoActive'), hrAfter: false },
- { id: 'directMilitaryTooltip', checked: myGM.getValue('module_directMilitaryTtActive', true), label: Language.$('optionPanel_section_module_label_directMilitaryTtActive'), hrAfter: false },
- { id: 'unitInfo', checked: myGM.getValue('module_unitInfoActive', true), label: Language.$('optionPanel_section_module_label_unitInfoActive'), hrAfter: true },
- { id: 'hideBirds', checked: myGM.getValue('module_hideBirdsActive', true), label: Language.$('optionPanel_section_module_label_hideBirdsActive'), hrAfter: false },
- { id: 'noCenterTownAdvisor', checked: myGM.getValue('module_nctAdvisorActive', true), label: Language.$('optionPanel_section_module_label_nctAdvisorActive'), hrAfter: false },
- { id: 'memberInformation', checked: myGM.getValue('module_memberInfoActive', false), label: Language.$('optionPanel_section_module_label_memberInfoActive'), hrAfter: false }
- );
- // Create the checkboxes.
- this.addCheckboxes(updateTable, cbData);
- // Add the button to save the settings.
- this.addSaveButton(contentWrapper);
- },
- /**
- * Creates the content of the update part.
- *
- * @param element contentWrapper
- * The wrapper where the content should be added.
- */
- createUpdateContent: function(contentWrapper) {
- // Create options table.
- var updateTable = this.addOptionsTable(contentWrapper);
- // Array for update interval values and names.
- var opts = new Array(
- { value: 3600, name: Language.$('optionPanel_section_update_label_interval_option_hour') },
- { value: 43200, name: Language.$('optionPanel_section_update_label_interval_option_hour12') },
- { value: 86400, name: Language.$('optionPanel_section_update_label_interval_option_day') },
- { value: 259200, name: Language.$('optionPanel_section_update_label_interval_option_day3') },
- { value: 604800, name: Language.$('optionPanel_section_update_label_interval_option_week') },
- { value: 1209600, name: Language.$('optionPanel_section_update_label_interval_option_week2') },
- { value: 2419200, name: Language.$('optionPanel_section_update_label_interval_option_week4') }
- );
- // Create the update interval select.
- this.addSelect(updateTable, 'updateInterval', myGM.getValue('updater_updateInterval', 3600), opts, Language.$('optionPanel_section_update_label_interval_description'));
- // Prepare the update link table row.
- var updateLinkTr = this.addOptionsTableRow(updateTable, true);
- updateLinkTr.firstChild.classList.add('center');
- updateLinkTr.firstChild.classList.remove('left');
- // Add the link for manual updates.
- var updateLink = myGM.addElement('a', updateLinkTr.firstChild);
- updateLink.href = '#';
- updateLink.innerHTML = Language.$('optionPanel_section_update_label_manual_text1') + '"' + scriptInfo.name + '"' + Language.$('optionPanel_section_update_label_manual_text2');
- updateLink.addEventListener('click', Updater.doManualUpdate, false);
- // Add the button to save the settings.
- this.addSaveButton(contentWrapper);
- },
- /**
- * Create the content of the resource information / missing resources part.
- *
- * @param element contentWrapper
- * The wrapper where the content should be added.
- */
- createResInfoMissingResContent: function(contentWrapper) {
- // Create options table.
- var selectionTable = this.addOptionsTable(contentWrapper);
- var checkboxTable = this.addOptionsTable(contentWrapper);
- // Array for update interval values and names.
- var optsAlign = new Array(
- { value: 'alignRight', name: Language.$('optionPanel_section_resInfoMissingRes_label_align_right') },
- { value: 'alignLeft', name: Language.$('optionPanel_section_resInfoMissingRes_label_align_left') },
- { value: 'withSeparation', name: Language.$('optionPanel_section_resInfoMissingRes_label_align_rightWithSeparation') }
- );
- // Create the hourly income style select.
- this.addSelect(selectionTable, 'hourlyIncomeStyle', myGM.getValue('resourceInfo_hourlyIncomeStyle', 'alignRight'), optsAlign, Language.$('optionPanel_section_resInfoMissingRes_label_hourlyIncomeStyle'));
- // Array for update interval values and names.
- var optsOrientation = new Array(
- { value: 'vertical', name: Language.$('optionPanel_section_resInfoMissingRes_label_orientation_vertical') },
- { value: 'horizontal', name: Language.$('optionPanel_section_resInfoMissingRes_label_orientation_horizontal') },
- { value: 'horizontalFull', name: Language.$('optionPanel_section_resInfoMissingRes_label_orientation_horizontalFull') }
- );
- // Create the hourly income style select.
- this.addSelect(selectionTable, 'capacityInfoStyle', myGM.getValue('resourceInfo_capacityStyle_orientation', 'vertical'), optsOrientation, Language.$('optionPanel_section_resInfoMissingRes_label_capacityOrientationStyle'));
- // Get the checkbox data.
- var cbData = new Array(
- { id: 'hasBorder', checked: myGM.getValue('resourceInfo_capacityStyle_hasBorder', true), label: Language.$('optionPanel_section_resInfoMissingRes_label_hasBorder'), hrAfter: false },
- { id: 'showBranchRes', checked: myGM.getValue('resourceInfo_showBranchRes', true), label: Language.$('optionPanel_section_resInfoMissingRes_label_showBranchRes'), hrAfter: true },
- { id: 'showPositive', checked: myGM.getValue('missingRes_showPositive', true), label: Language.$('optionPanel_section_resInfoMissingRes_label_showPositive'), hrAfter: false },
- { id: 'showColoured', checked: myGM.getValue('missingRes_showColoured', true), label: Language.$('optionPanel_section_resInfoMissingRes_label_showColoured'), hrAfter: false }
- );
- // Create the checkboxes.
- this.addCheckboxes(checkboxTable, cbData);
- // Add the button to save the settings.
- this.addSaveButton(contentWrapper);
- },
- /**
- * Create the content of the zoom part.
- *
- * @param element contentWrapper
- * The wrapper where the content should be added.
- */
- createZoomContent: function(contentWrapper) {
- // Create the options tables.
- var factorTable = this.addOptionsTable(contentWrapper);
- var scaleChildrenTable = this.addOptionsTable(contentWrapper);
- var accessKeysTable = this.addOptionsTable(contentWrapper);
- // Set the description data.
- var descriptionRowData = new Array(
- { parent: scaleChildrenTable, text: Language.$('optionPanel_section_zoom_label_scaleChildren_description') },
- { parent: accessKeysTable, text: Language.$('optionPanel_section_zoom_label_accessKeys') }
- );
- // Add the descriptions.
- for(var i = 0; i < descriptionRowData.length; i++) {
- // Add the table row.
- var descriptionTr = this.addOptionsTableRow(descriptionRowData[i]['parent'], true);
- // Add the description.
- var description = myGM.addElement('p', descriptionTr.firstChild);
- description.innerHTML = descriptionRowData[i]['text'];
- }
- // Set the data for the factor select fields.
- var factorSelects = new Array(
- { id: 'zoomWorld', selected: myGM.getValue('zoom_worldFactor', 100), labelText: Language.$('optionPanel_section_zoom_label_zoomFactor_world') },
- { id: 'zoomIsland', selected: myGM.getValue('zoom_islandFactor', 100), labelText: Language.$('optionPanel_section_zoom_label_zoomFactor_island') },
- { id: 'zoomTown', selected: myGM.getValue('zoom_townFactor', 100), labelText: Language.$('optionPanel_section_zoom_label_zoomFactor_town') }
- );
- // Set the zoom factor values and names.
- var opts = new Array();
- for(var i = ZoomFunction.minZoom; i <= ZoomFunction.maxZoom; i = i + ZoomFunction.zoomStep) {
- opts.push({ value: i, name: i + '%' });
- }
- // Add all factor select fields.
- for(var i = 0; i < factorSelects.length; i++) {
- this.addSelect(factorTable, factorSelects[i]['id'], factorSelects[i]['selected'], opts, factorSelects[i]['labelText']);
- }
- // Set the scale children checkbox data.
- var scaleChildrenCbData = new Array(
- { id: 'zoomScaleChildrenWorld', checked: myGM.getValue('zoom_worldScaleChildren', true), label: Language.$('optionPanel_section_zoom_label_scaleChildren_world') },
- { id: 'zoomScaleChildrenIsland', checked: myGM.getValue('zoom_islandScaleChildren', true), label: Language.$('optionPanel_section_zoom_label_scaleChildren_island') },
- { id: 'zoomScaleChildrenTown', checked: myGM.getValue('zoom_townScaleChildren', true), label: Language.$('optionPanel_section_zoom_label_scaleChildren_town') }
- );
- // Add the scale children checkboxes
- this.addCheckboxes(scaleChildrenTable, scaleChildrenCbData);
- // Set the scale children checkbox data.
- var accessKeysCbData = new Array(
- { id: 'zoomCtrlPressed', checked: myGM.getValue('zoom_ctrlPressed', true), label: Language.$('general_ctrl') },
- { id: 'zoomAltPressed', checked: myGM.getValue('zoom_altPressed', false), label: Language.$('general_alt') },
- { id: 'zoomShiftPressed', checked: myGM.getValue('zoom_shiftPressed', false), label: Language.$('general_shift') }
- );
- // Add the scale children checkboxes
- this.addCheckboxes(accessKeysTable, accessKeysCbData);
- // Add the button to save the settings.
- this.addSaveButton(contentWrapper);
- },
- /**
- * Create the content of the message signature part.
- *
- * @param element contentWrapper
- * The wrapper where the content should be added.
- */
- createMessageSigContent: function(contentWrapper) {
- // Create the options tables.
- var settingsTable = this.addOptionsTable(contentWrapper);
- var globalSigTable = this.addOptionsTable(contentWrapper);
- var serverSigTable = this.addOptionsTable(contentWrapper);
- // Get the checkbox data.
- var cbData = new Array(
- { id: 'useServerSignature', checked: myGM.getValue('messageSignature_useServerSignature_' + General.getServerCode(), false), label: Language.$('optionPanel_section_messageSignature_label_useServerSignature') },
- { id: 'placementTop', checked: myGM.getValue('messageSignature_placementTop', true), label: Language.$('optionPanel_section_messageSignature_label_placementTop') }
- );
- // Create the checkboxes.
- this.addCheckboxes(settingsTable, cbData);
- // Set the text area data.
- var textAreaData = new Array(
- { id: 'globalSignatureText', parent: globalSigTable, text: Language.$('optionPanel_section_messageSignature_label_signatureText_global'), value: myGM.getValue('messageSignature_globalSignature', '') },
- { id: 'serverSignatureText', parent: serverSigTable, text: Language.$('optionPanel_section_messageSignature_label_signatureText_server'), value: myGM.getValue('messageSignature_serverSignature_' + General.getServerCode(), '') }
- );
- // Add the text areas.
- for(var i = 0; i < textAreaData.length; i++) {
- // Add the label table row.
- var labelTr = this.addOptionsTableRow(textAreaData[i]['parent'], true);
- // Add the label.
- var label = myGM.addElement('p', labelTr.firstChild);
- label.innerHTML = textAreaData[i]['text'];
- // Add the text field table row.
- var textAreaTr = this.addOptionsTableRow(textAreaData[i]['parent'], true);
- // Add the text area.
- var textArea = myGM.addElement('textarea', textAreaTr.firstChild, textAreaData[i]['id'], new Array('textfield', myGM.prefix + 'SignatureInput'));
- textArea.value = textAreaData[i]['value'];
- }
- // Add the button to save the settings.
- this.addSaveButton(contentWrapper);
- },
- /**
- * Add a new options table.
- *
- * @param element wrapper
- * The wrapper where the table should be added.
- *
- * @return element
- * The body of the new table.
- */
- addOptionsTable: function(wrapper) {
- // Create table and tablebody.
- var table = myGM.addElement('table', wrapper, null, new Array('moduleContent', 'table01'));
- var tableBody = myGM.addElement('tbody', table);
- // Return the table body.
- return tableBody;
- },
- /**
- * Adds a new table row to a options table.
- *
- * @param element optionsTableBody
- * The table body where the table should be added.
- * @param boolean oneCell
- * Decides if there is one cell or there are two cells.
- *
- * @return element
- * The new table row.
- */
- addOptionsTableRow: function(optionsTableBody, oneCell) {
- // Create the new table row.
- var tr = myGM.addElement('tr', optionsTableBody);
- // Create first cell.
- var td1 = myGM.addElement('td', tr);
- // If just ond cell.
- if(oneCell) {
- // Set width of cell to width of two cells.
- td1.colSpan = 2;
- td1.classList.add('left');
- // Otherwise.
- } else {
- // Create second cell.
- myGM.addElement('td', tr, null, 'left');
- }
- // Return the table row.
- return tr;
- },
- /**
- * Creates new checkboxes and adds it to a option table, specified as parentTable.
- *
- * @param element parentTable
- * The parent of the new checkboxes.
- * @param mixed[] cbData
- * A array containing the data of the checkboxes.
- */
- addCheckboxes: function(parentTable, cbData) {
- // Create the checkboxes.
- for(var i = 0; i < cbData.length; i++) {
- // Create table row.
- var tr = this.addOptionsTableRow(parentTable, true);
- // Create the wrapper for the checkbox and the label.
- var wrapper = myGM.addElement('div', tr.firstChild, null, 'cbWrapper');
- // Create the checkbox and set the attributes.
- var cb = myGM.addElement('input', wrapper, cbData[i]['id'] + 'Cb', 'checkbox');
- cb.type = 'checkbox';
- cb.title = cbData[i]['label'];
- cb.checked = cbData[i]['checked'] ? 'checked' : '';
- if(cbData[i]['hrAfter'] == true) {
- var spacer = this.addOptionsTableRow(parentTable, true);
- myGM.addElement('hr', spacer.firstChild);
- }
- }
- // Replace the checkboxes for better appearance.
- ika.controller.replaceCheckboxes();
- },
- /**
- * Creates a new select field and adds it to a option table, specified as parentTable.
- *
- * @param element parentTable
- * The parent table of the new select field.
- * @param String id
- * The last part of the id of the select field.
- * @param boolean selected
- * The value of the selected option.
- * @param mixed[] opts
- * An array with the names an values of the options.
- * @param String labelText
- * The text of the select label.
- */
- addSelect: function(parentTable, id, selected, opts, labelText) {
- // Create table row.
- var tr = this.addOptionsTableRow(parentTable, false);
- // Create label.
- var selectLabel = myGM.addElement('span', tr.firstChild);
- selectLabel.innerHTML = labelText;
- // Create the wrapper for the select.
- var wrapper = myGM.addElement('div', tr.lastChild, id + 'SelectContainer', new Array('select_container', 'size175'), new Array(['position', 'relative']));
- // Create the select field.
- var select = myGM.addElement('select', wrapper, id + 'Select', 'dropdown');
- // Add the Options.
- for(var i = 0; i < opts.length; i++) {
- // Create an option.
- var option = myGM.addElement('option', select);
- // Set the value and the name.
- option.value = opts[i]['value'];
- option.innerHTML = opts[i]['name'];
- // If the option is selected, set selected to true.
- if(option.value == selected) {
- option.selected = 'selected';
- }
- }
- // Replace the dropdown for better appearance.
- ika.controller.replaceDropdownMenus();
- },
- /**
- * Creates a commit Button and adds it to a parent.
- *
- * @param element parent
- * The parent element.
- *
- * @return element
- * The save button.
- */
- addSaveButton: function(parent) {
- // Create the button wrapper.
- var buttonWrapper = myGM.addElement('div', parent, null, 'centerButton');
- // Create the button.
- var saveButton = myGM.addElement('input', buttonWrapper, null, 'button');
- saveButton.type = 'submit';
- saveButton.value = Language.$('optionPanel_save');
- // Add a click action to the button.
- saveButton.addEventListener('click', EventHandling.optionPanel.saveSettings, false);
- return saveButton;
- },
- /**
- * Save the settings.
- */
- saveSettings: function() {
- // Save the module settings.
- myGM.setValue('module_updateActive', myGM.$('#' + myGM.prefix + 'updateCb').checked);
- myGM.setValue('module_incomeActive', myGM.$('#' + myGM.prefix + 'incomeOnTopCb').checked);
- myGM.setValue('module_urtShortActive', myGM.$('#' + myGM.prefix + 'upkeepReductionCb').checked);
- myGM.setValue('module_missingResActive', myGM.$('#' + myGM.prefix + 'missingResourcesCb').checked);
- myGM.setValue('module_resourceInfoActive', myGM.$('#' + myGM.prefix + 'resourceInformationCb').checked);
- myGM.setValue('module_capacityInfoActive', myGM.$('#' + myGM.prefix + 'capacityInformationCb').checked);
- myGM.setValue('module_easyAccessActive', myGM.$('#' + myGM.prefix + 'easyAccessCb').checked);
- myGM.setValue('module_zoomActive', myGM.$('#' + myGM.prefix + 'zoomCb').checked);
- myGM.setValue('module_messageSigActive', myGM.$('#' + myGM.prefix + 'messageSignatureCb').checked);
- myGM.setValue('module_easyCircularMsgActive', myGM.$('#' + myGM.prefix + 'easyCircularMessageCb').checked);
- myGM.setValue('module_replaceUrlsActive', myGM.$('#' + myGM.prefix + 'replaceUrlsCb').checked);
- myGM.setValue('module_colonizingLinksActive', myGM.$('#' + myGM.prefix + 'colonizingLinksCb').checked);
- myGM.setValue('module_lcMoveActive', myGM.$('#' + myGM.prefix + 'loadingCircleMoveCb').checked);
- myGM.setValue('module_ttAutoActive', myGM.$('#' + myGM.prefix + 'tooltipsAutoCb').checked);
- myGM.setValue('module_directMilitaryTtActive', myGM.$('#' + myGM.prefix + 'directMilitaryTooltipCb').checked);
- myGM.setValue('module_unitInfoActive', myGM.$('#' + myGM.prefix + 'unitInfoCb').checked);
- myGM.setValue('module_hideBirdsActive', myGM.$('#' + myGM.prefix + 'hideBirdsCb').checked);
- myGM.setValue('module_nctAdvisorActive', myGM.$('#' + myGM.prefix + 'noCenterTownAdvisorCb').checked);
- myGM.setValue('module_memberInfoActive', myGM.$('#' + myGM.prefix + 'memberInformationCb').checked);
- // Save the update settings.
- myGM.setValue('updater_updateInterval', General.getInt(General.getSelectValue('updateIntervalSelect')));
- // Save the resource information / missing resources settings.
- myGM.setValue('resourceInfo_hourlyIncomeStyle', General.getSelectValue('hourlyIncomeStyleSelect'));
- myGM.setValue('resourceInfo_capacityStyle_orientation', General.getSelectValue('capacityInfoStyleSelect'));
- myGM.setValue('resourceInfo_capacityStyle_hasBorder', myGM.$('#' + myGM.prefix + 'hasBorderCb').checked);
- myGM.setValue('resourceInfo_showBranchRes', myGM.$('#' + myGM.prefix + 'showBranchResCb').checked);
- myGM.setValue('missingRes_showPositive', myGM.$('#' + myGM.prefix + 'showPositiveCb').checked);
- myGM.setValue('missingRes_showColoured', myGM.$('#' + myGM.prefix + 'showColouredCb').checked);
- // Save the zoom function settings.
- myGM.setValue('zoom_worldFactor', General.getInt(General.getSelectValue('zoomWorldSelect')));
- myGM.setValue('zoom_islandFactor', General.getInt(General.getSelectValue('zoomIslandSelect')));
- myGM.setValue('zoom_townFactor', General.getInt(General.getSelectValue('zoomTownSelect')));
- myGM.setValue('zoom_worldScaleChildren', myGM.$('#' + myGM.prefix + 'zoomScaleChildrenWorldCb').checked);
- myGM.setValue('zoom_islandScaleChildren', myGM.$('#' + myGM.prefix + 'zoomScaleChildrenIslandCb').checked);
- myGM.setValue('zoom_townScaleChildren', myGM.$('#' + myGM.prefix + 'zoomScaleChildrenTownCb').checked);
- myGM.setValue('zoom_ctrlPressed', myGM.$('#' + myGM.prefix + 'zoomCtrlPressedCb').checked);
- myGM.setValue('zoom_altPressed', myGM.$('#' + myGM.prefix + 'zoomAltPressedCb').checked);
- myGM.setValue('zoom_shiftPressed', myGM.$('#' + myGM.prefix + 'zoomShiftPressedCb').checked);
- // Save the message signature function settings.
- myGM.setValue('messageSignature_useServerSignature_' + General.getServerCode(), myGM.$('#' + myGM.prefix + 'useServerSignatureCb').checked);
- myGM.setValue('messageSignature_placementTop', myGM.$('#' + myGM.prefix + 'placementTopCb').checked);
- myGM.setValue('messageSignature_globalSignature', myGM.$('#' + myGM.prefix + 'globalSignatureText').value);
- myGM.setValue('messageSignature_serverSignature_' + General.getServerCode(), myGM.$('#' + myGM.prefix + 'serverSignatureText').value);
- // Show success hint.
- General.showTooltip('cityAdvisor', 'confirm', Language.$('general_successful'));
- }
- };
- /**
- * Functions for zooming world, island and town view.
- */
- ZoomFunction = {
- /**
- * The minimal zoom factor in percent.
- */
- minZoom: 55,
- /**
- * The maximal zoom factor in percent.
- */
- maxZoom: 150,
- /**
- * The step between two zoom factors in percent.
- */
- zoomStep: 5,
- /**
- * Init the zooming.
- */
- init: function() {
- // Get the min zoom.
- var minZoom = Math.round(ika.worldview_scale_min * 100);
- minZoom = minZoom + ((minZoom % 5 == 0) ? 0 : (5 - minZoom % 5));
- // Set the max and min zoom.
- this.minZoom = minZoom;
- ika.worldview_scale_min = minZoom / 100;
- ika.worldview_scale_max = this.maxZoom / 100;
- // Change the mousewheel listener, so that it is possible to cheack if there are also keys pressed.
- this.changeMouseWheelListener();
- // Get the zooming factor.
- var factor = myGM.getValue('zoom_' + View.name + 'Factor', 100);
- // Add the zoom Buttons.
- this.addZoomButtons();
- // Zoom.
- this.zoom(factor);
- },
- /**
- * Add the Buttons for zooming to the view.
- */
- addZoomButtons: function() {
- // Get the the script toolbar
- var scriptToolbar = myGM.$('#' + myGM.prefix + 'toolbar');
- // Create the zoom buttons.
- var zoomWrapper = myGM.addElement('div', scriptToolbar, 'zoomWrapper');
- var zoomIn = myGM.addElement('div', zoomWrapper, 'zoomIn', 'maximizeImg');
- var zoomFactor = myGM.addElement('div', zoomWrapper, 'zoomFactor');
- var zoomOut = myGM.addElement('div', zoomWrapper, 'zoomOut', 'minimizeImg');
- // Set the button title.
- zoomIn.title = Language.$('zoomFunction_zoomIn');
- zoomFactor.title = Language.$('zoomFunction_zoomFactor');
- zoomOut.title = Language.$('zoomFunction_zoomOut');
- // Add the event listener.
- zoomIn.addEventListener('click', EventHandling.zoomFunction.zoomIn, false);
- zoomOut.addEventListener('click', EventHandling.zoomFunction.zoomOut, false);
- // Add the styles.
- myGM.addStyle(
- "#" + myGM.prefix + "zoomWrapper { position: absolute; top: 2px; right: 0px; width: 72px; transform: scale(0.75); scale(0.75); -o-transform: scale(0.75); -webkit-transform: scale(0.75); } \
- #" + myGM.prefix + "zoomIn { position: absolute; } \
- #" + myGM.prefix + "zoomFactor { position: absolute; left: 20px; width: 35px; text-align: center; } \
- #" + myGM.prefix + "zoomOut { position: absolute; left: 58px; }"
- );
- },
- /**
- * Changes the mouse wheel listener so that it could be used with access keys.
- */
- changeMouseWheelListener: function() {
- // Set the defaut scrollDiv id.
- var scrollDivId = '#worldmap';
- // If wolrd view, change the scroll div id.
- if(View.name == 'world') {
- scrollDivId = '#map1';
- }
- // Remove the old mouse wheel listener. (with the use of Ikariam-jQuery)
- win.$(scrollDivId).unbind('mousewheel');
- // Add the new mouse wheel listener.
- var scrollDiv = myGM.$(scrollDivId);
- scrollDiv.addEventListener('DOMMouseScroll', EventHandling.zoomFunction.mouseScroll, false);
- scrollDiv.addEventListener('mousewheel', EventHandling.zoomFunction.mouseScroll, false);
- },
- /**
- * Zooms the view.
- *
- * @param int factor
- * The factor which is used.
- */
- zoom: function(factor) {
- // If the factor is bigger / smaller than allowed, set it to the max / min allowed.
- factor = factor > this.maxZoom ? this.maxZoom : (factor < this.minZoom ? this.minZoom : factor);
- // Store the zoom factor.
- myGM.setValue('zoom_' + View.name + 'Factor', factor);
- // Update the zoom factor which is shown to the user and the zoom buttons.
- var zoomFactorDiv = myGM.$('#' + myGM.prefix + 'zoomFactor');
- var zoomIn = myGM.$('#' + myGM.prefix + 'zoomIn');
- var zoomOut = myGM.$('#' + myGM.prefix + 'zoomOut');
- // Zoom factor.
- if(zoomFactorDiv) {
- zoomFactorDiv.innerHTML = factor + '%';
- }
- // Zoom in.
- if(zoomIn) {
- // If it is not allowed to zoom in, hide the zoom in button.
- if(factor >= this.maxZoom) {
- zoomIn.classList.add('invisible');
- // Otherwise: Show the zoom in button.
- } else {
- zoomIn.classList.remove('invisible');
- }
- }
- // Zoom out.
- if(zoomOut) {
- // If it is not allowed to zoom out, hide the zoom out button.
- if(factor <= this.minZoom) {
- zoomOut.classList.add('invisible');
- // Otherwise: Show the zoom out button.
- } else {
- zoomOut.classList.remove('invisible');
- }
- }
- // Get the factor as normal number, not as percentage.
- var factorNew = factor / 100.0;
- // Get the game scaling factor depending on the view.
- var scale = 0;
- switch(View.name) {
- case 'world':
- break;
- case 'island':
- scale = ika.worldview_scale_island;
- break;
- case 'town':
- scale = ika.worldview_scale_city;
- break;
- default:
- return;
- break;
- }
- // It is the world view, zoom it.
- if(View.name == 'world') {
- this.zoomWorld(factorNew);
- // Otherwise call the ikariam zoom function.
- } else {
- // Get the number of steps to zoom.
- var stepNumber = Math.round((factorNew - scale) / .05);
- // Get the center position of the worldmap.
- var worldview = myGM.$('#worldview');
- var posX = worldview.offsetLeft + worldview.offsetWidth / 2;
- var posY = worldview.offsetTop + worldview.offsetHeight / 2;
- // Zoom.
- ika.controller.scaleWorldMap(stepNumber, posX, posY);
- }
- // Scale child elements if enabled.
- if(myGM.getValue('zoom_' + View.name + 'ScaleChildren', true)) ZoomFunction.scaleChildren(factorNew);
- // Return the factor in percent.
- return factor;
- },
- /**
- * Zoom the world view.
- *
- * @param float factor
- * The factor which is used.
- */
- zoomWorld: function(factor) {
- // Get the factor the scrollcover must be moved.
- var translateXY = (100 - 100 / factor) / 2;
- // Get the new height and width of the scrollcover.
- var heightWidth = 100 / factor;
- // Overwrite the old style.
- myGM.addStyle(
- "#scrollcover { transform: scale(" + factor + ") translate(" + translateXY + "%, " + translateXY + "%); -o-transform: scale(" + factor + ") translate(" + translateXY + "%, " + translateXY + "%); -webkit-transform: scale(" + factor + ") translate(" + translateXY + "%, " + translateXY + "%); height: " + heightWidth + "% !important; width: " + heightWidth + "% !important; }",
- 'zoomWorld', true
- );
- // Get the map.
- var map = myGM.$('#map1');
- // Set the new offset.
- var newWmTop = 0;
- var newWmLeft = 0;
- // Apply the new offset to the map.
- map.style.top = newWmTop + 'px';
- map.style.left = newWmLeft + 'px';
- },
- /**
- * Scales the children of the worldmap / island view.
- *
- * @param float factor
- * The factor which is used.
- * @param String view
- * The name of the view.
- */
- scaleChildren: function(factor) {
- // Which view is used?
- switch(View.name) {
- // Worldview.
- case 'world':
- myGM.addStyle(
- ".islandTile .wonder, .islandTile .tradegood, .islandTile .cities" + (factor < 1 ? ", .ownerState" : "") + " { transform: scale(" + 1 / factor + "); -o-transform: scale(" + 1 / factor + "); -webkit-transform: scale(" + 1 / factor + "); } \
- .islandTile .cities { bottom: 10px !important; }",
- 'scaleChildren', true
- );
- break;
- // Island view.
- case 'island':
- myGM.addStyle(
- ".cityLocation .scroll_img { transform: scale(" + 1 / factor + "); -o-transform: scale(" + 1 / factor + "); -webkit-transform: scale(" + 1 / factor + "); }",
- 'scaleChildren', true
- );
- break;
- // Town view.
- case 'town':
- myGM.addStyle(
- ".building .timetofinish { transform: scale(" + 1 / factor + "); -o-transform: scale(" + 1 / factor + "); -webkit-transform: scale(" + 1 / factor + "); }",
- 'scaleChildren', true
- );
- break;
- // Default: do nothing.
- default:
- return;
- break;
- }
- }
- };
- /**
- * Function for showing the missing resources directly in the ruction / update view.
- */
- MissingResources = {
- /**
- * Init the missing ressources.
- */
- init: function() {
- // Set the required styles.
- myGM.addStyle(
- "#sidebar #buildingUpgrade ul.resources li { width: 120px; } \
- #sidebar #buildingUpgrade ul.resources li.time { width: 60px !important; } \
- #sidebar ." + myGM.prefix + "missingResources { float: right; }"
- );
- },
- /**
- * Shows the missing resources in the building ground popup.
- */
- showInBuildingGround: function() {
- // Show the resources.
- this.show(false);
- },
- /**
- * Shows the missing resources in the sidebar.
- */
- showInSidebar: function() {
- // Show the resources.
- this.show(true);
- // Add an event listener to update the shown resources.
- myGM.$('#cityResources').addEventListener('DOMSubtreeModified', EventHandling.missingResources.resourcesUpdated, false);
- },
- /**
- * Shows the missing resources in the place which is given.
- *
- * @param boolean isSidebar
- * If the place where to show is the sidebar.
- */
- show: function(isSidebar, update) {
- // Store the current resources.
- var current = Array();
- current.push(ika.model.currentResources.resource); // Wood.
- current.push(ika.model.currentResources[1]); // Wine.
- current.push(ika.model.currentResources[2]); // Marble.
- current.push(ika.model.currentResources[3]); // Crystal.
- current.push(ika.model.currentResources[4]); // Sulfur.
- // Store the resource names.
- var resourceName = new Array('wood', 'wine', 'marble', 'glass', 'sulfur');
- // Get all possible wrappers.
- var wrapper = myGM.$$('#' + (isSidebar ? 'sidebar' : 'buildingGround') + ' .resources');
- // Loop over all wrappers.
- for(var i = 0; i < wrapper.length; i++) {
- // Loop over all resources.
- for(var k = 0; k < resourceName.length; k++) {
- // Get the resource node.
- var node = myGM.$('.' + resourceName[k], wrapper[i]);
- // If the node exist, show the missing resources.
- if(node) {
- // Get the missing resource number.
- var missing = current[k] - (update ? General.getInt(node.lastChild.previousSibling.nodeValue) : General.getInt(node.lastChild.nodeValue));
- // If there are resources missing.
- if(missing < 0 || (myGM.getValue('missingRes_showPositive', true) && isSidebar)) {
- // Show the missing resource info.
- var show = update ? myGM.$('#' + myGM.prefix + 'missingResources' + resourceName[k]) : myGM.addElement('span', node, 'missingResources' + resourceName[k], 'missingResources', null, true);
- show.innerHTML = (isSidebar ? '' : ' (') + General.formatToIkaNumber(missing, myGM.getValue('missingRes_showColoured', true), true) + (isSidebar ? '' : ')');
- }
- }
- }
- }
- }
- };
- /**
- * Functions for showing the hourly production directly in the town view.
- * Also adds the daily Production to the resource tooltip.
- */
- ResourceInfo = {
- /**
- * Storage for the last tradegood.
- */
- lastTradegood: null,
- /**
- * Inits the resource info.
- */
- init: function() {
- // If the city is owned by the player.
- if(ika.model.isOwnCity == true) {
- // Set the styles.
- this.setStyles();
- // Add the resource info.
- if(myGM.getValue('module_resourceInfoActive', true)) this.addHourlyResourceInfo();
- // Add the capacity info.
- if(myGM.getValue('module_capacityInfoActive', true)) this.addCapacityInfo();
- }
- },
- /**
- * Sets the styles that are required for the resource info.
- */
- setStyles: function() {
- // Probleme: resourceInfo deaktiviert + alle.
- var resourceInfoActive = myGM.getValue('module_resourceInfoActive', true);
- var capacityInfoActive = myGM.getValue('module_capacityInfoActive', true);
- var hourlyIncomeStyle = myGM.getValue('resourceInfo_hourlyIncomeStyle', 'alignRight');
- var capacityStyleOrientation = myGM.getValue('resourceInfo_capacityStyle_orientation', 'vertical');
- // If the resource info is active.
- if(resourceInfoActive) {
- // Define the style for the resources wrapper.
- var resourcesStyle = {
- lineHeight: (capacityInfoActive && capacityStyleOrientation == 'horizontal') ? 'line-height: 9px !important;' : 'line-height: 11px !important;',
- align: (hourlyIncomeStyle != 'alignLeft') ? ' text-align: right;' : '',
- fontSize: (capacityInfoActive && capacityStyleOrientation != 'horizontalFull') ? ' font-size: 11px;' : '',
- height: (capacityInfoActive && capacityStyleOrientation == 'horizontalFull') ? ' height: 32px !important;' : '',
- top: (capacityInfoActive && capacityStyleOrientation == 'horizontalFull') ? ' top: -2px !important;' : '',
- paddingLeft: (capacityInfoActive && capacityStyleOrientation == 'vertical' && hourlyIncomeStyle == 'alignLeft') ? ' padding-left: 38px !important;' : ''
- };
- var resStyle = '#resources_wood, #resources_wine, #resources_marble, #resources_glass, #resources_sulfur { '
- + resourcesStyle.lineHeight
- + resourcesStyle.align
- + resourcesStyle.fontSize
- + resourcesStyle.height
- + resourcesStyle.top
- + resourcesStyle.paddingLeft
- + ' } ';
- // Define the style for the global menu resources.
- var globalMenuStyle = {
- padding: (hourlyIncomeStyle != 'alignLeft') ? 'padding-right: 4px;' : ''
- };
- var globMenuStyle = '#js_GlobalMenu_wood, #js_GlobalMenu_wine, #js_GlobalMenu_marble, #js_GlobalMenu_crystal, #js_GlobalMenu_sulfur { '
- + globalMenuStyle.padding
- + ' } ';
- // Define the style for the hourly income.
- var incomeStyle = {
- fontSize: (capacityInfoActive && capacityStyleOrientation != 'horizontalFull') ? 'font-size: 9px;' : 'font-size: 11px;',
- paddingRight: (hourlyIncomeStyle != 'alignLeft') ? ' padding-right: 4px;' : ''
- };
- var hirStyle = '.' + myGM.prefix + 'hourlyIncomeResource { '
- + incomeStyle.fontSize
- + incomeStyle.paddingRight
- + ' } ';
- // Define the style for the resources wrapper with border as separation.
- var separationStyle = {
- border: (hourlyIncomeStyle == 'withSeparation') ? 'border-right: 1px dotted #542C0F;' : ''
- };
- var sepStyle = '#resources_wood, #resources_wine, #resources_marble, #resources_glass { '
- + separationStyle.border
- + ' } ';
- // Add all styles to the ikariam page.
- var resInfoStyle = resStyle + globMenuStyle + hirStyle + sepStyle;
- myGM.addStyle(resInfoStyle, 'hourlyIncomeStyle', true);
- // Otherwise: If the capacity info is active.
- } else if(capacityInfoActive) {
- // Define the style for the resources wrapper.
- var resourcesStyle = {
- lineHeight: (capacityStyleOrientation == 'horizontal') ? 'line-height: 12px !important;' : ((capacityStyleOrientation == 'vertical') ? ' line-height: 24px !important;' : ''),
- align: (hourlyIncomeStyle != 'alignLeft') ? ' text-align: right;' : '',
- fontSize: (capacityStyleOrientation == 'vertical') ? ' font-size: 11px;' : '',
- height: (capacityStyleOrientation == 'horizontalFull') ? ' height: 32px !important;' : '',
- top: (capacityStyleOrientation == 'horizontalFull') ? ' top: -2px !important;' : '',
- paddingLeft: (capacityStyleOrientation == 'vertical' && hourlyIncomeStyle == 'alignLeft') ? ' padding-left: 38px !important;' : ''
- };
- var resStyle = '#resources_wood, #resources_wine, #resources_marble, #resources_glass, #resources_sulfur { '
- + resourcesStyle.lineHeight
- + resourcesStyle.align
- + resourcesStyle.fontSize
- + resourcesStyle.height
- + resourcesStyle.top
- + resourcesStyle.paddingLeft
- + ' } ';
- // Define the style for the global menu resources.
- var globalMenuStyle = {
- padding: (hourlyIncomeStyle != 'alignLeft') ? 'padding-right: 4px;' : ''
- };
- var globMenuStyle = '#js_GlobalMenu_wood, #js_GlobalMenu_wine, #js_GlobalMenu_marble, #js_GlobalMenu_crystal, #js_GlobalMenu_sulfur { '
- + globalMenuStyle.padding
- + ' } ';
- // Define the style for the resources wrapper with border as separation.
- var separationStyle = {
- border: (hourlyIncomeStyle == 'withSeparation') ? 'border-right: 1px dotted #542C0F;' : ''
- };
- var sepStyle = '#resources_wood, #resources_wine, #resources_marble, #resources_glass { '
- + separationStyle.border
- + ' } ';
- // Add all styles to the ikariam page.
- var resInfoStyle = resStyle + globMenuStyle + sepStyle;
- myGM.addStyle(resInfoStyle, 'hourlyIncomeStyle', true);
- }
- // If the capacity info is active.
- if(capacityInfoActive) {
- // Define the style for the bar.
- var barStyle = '.' + myGM.prefix + 'bar { height: 100%; width: 100%; bottom: 0px; position: absolute; } ';
- // Define the style for the red bar.
- var redBarStyle = '.' + myGM.prefix + 'bar.' + myGM.prefix + 'red { background-color: #AA0000; } ';
- // Define the style for the red bar.
- var yellowBarStyle = '.' + myGM.prefix + 'bar.' + myGM.prefix + 'yellow { background-color: #FFD700; } ';
- // Define the style for the green bar.
- var greenBarStyle = '.' + myGM.prefix + 'bar.' + myGM.prefix + 'green { background-color: #669900; } ';
- // Define the style for the capacity information.
- var capacityInfoStyle = {
- position: 'position: absolute;',
- height: (capacityStyleOrientation == 'vertical') ? ' height: 21px;' : ' height: 4px;',
- width: (capacityStyleOrientation != 'vertical') ? ((capacityStyleOrientation == 'horizontal') ? ' width: 50px;' : ' width: 79px;') : ' width: 4px;',
- bottom: ' bottom: 4px;',
- right: (capacityStyleOrientation != 'vertical') ? ' right: 4px;' : '',
- marginLeft: (capacityStyleOrientation == 'vertical' && hourlyIncomeStyle == 'alignLeft') ? ' margin-left: -7px;' : ''
- };
- var capInfoStyle = '.' + myGM.prefix + 'capacityInfo { '
- + capacityInfoStyle.position
- + capacityInfoStyle.height
- + capacityInfoStyle.width
- + capacityInfoStyle.bottom
- + capacityInfoStyle.right
- + capacityInfoStyle.marginLeft
- + ' } ';
- // Define the style for the capacity information with border.
- var capacityInfoBorderStyle = {
- border: 'border: 1px inset #906646;',
- height: (capacityStyleOrientation == 'vertical') ? ' height: 20px;' : ' height: 3px;',
- width: (capacityStyleOrientation != 'vertical') ? ((capacityStyleOrientation == 'horizontal') ? ' width: 50px;' : ' width: 78px;') : ' width: 3px;',
- bottom: ' bottom: 3px;',
- right: (capacityStyleOrientation != 'vertical') ? ' right: 3px;' : ''
- };
- var capInfoBorderStyle = '.' + myGM.prefix + 'capacityInfo.' + myGM.prefix + 'border { '
- + capacityInfoBorderStyle.border
- + capacityInfoBorderStyle.height
- + capacityInfoBorderStyle.width
- + capacityInfoBorderStyle.bottom
- + capacityInfoBorderStyle.right
- + ' } ';
- // Add all styles to the ikariam page.
- var capacityInformationStyle = barStyle + redBarStyle + yellowBarStyle + greenBarStyle + capInfoStyle + capInfoBorderStyle;
- myGM.addStyle(capacityInformationStyle, 'capacityInfoStyle', true);
- }
- },
- /**
- * Show the hourly resource info.
- */
- addHourlyResourceInfo: function() {
- // If the info containers are already set, do nothing.
- if(myGM.$('#' + myGM.prefix + 'wood')) {
- return;
- }
- // Set all resource types.
- var types = new Array('wood', 'wine', 'marble', 'glass', 'sulfur');
- // Loop over all resource types.
- for(var i = 0; i < types.length; i++) {
- // Add the hourly info.
- myGM.addElement('span', myGM.$('#resources_' + types[i]), 'hourlyIncomeResource' + types[i], 'hourlyIncomeResource', null, true);
- // Add the daily info.
- var parent = myGM.$('#resources_' + types[i] + ' .tooltip');
- var classes = (i < 2) ? 'smallFont' : new Array('smallFont', 'invisible');
- var wrapper = myGM.addElement('p', parent, 'dailyIncomeResourceWrapper' + types[i], classes, null, null, myGM.$('p:nth-child(2)', parent));
- wrapper.innerHTML = Language.$('resourceInfo_dailyIncome_' + types[i]) + ' ';
- myGM.addElement('span', wrapper, 'dailyIncomeResource' + types[i]);
- }
- // Update the resource information.
- this.updateHourlyResourceInfo(true);
- },
- /**
- * Update the shown hourly resource information.
- */
- updateHourlyResourceInfo: function(firstRun) {
- // If the city is not owned by the player, stop the update.
- if(ika.model.isOwnCity != true) {
- return;
- }
- // Prefix for selection.
- var hourlyPrefix = '#' + myGM.prefix + 'hourlyIncomeResource';
- var dailyPrefix = '#' + myGM.prefix + 'dailyIncomeResource';
- // If the info containers are not set, set them.
- if(!myGM.$(hourlyPrefix + 'wood')) {
- this.init();
- }
- // Set all resource types.
- var types = new Array('wood', 'wine', 'marble', 'glass', 'sulfur');
- // Get some needed data.
- var producedTradegood = ika.model.producedTradegood;
- var tradegood = ika.model.tradegoodProduction * 3600 + 0.001;
- var resource = ika.model.resourceProduction * 3600 + 0.001;
- var wineSpending = ika.model.wineSpendings;
- var producesWine = ika.model.cityProducesWine;
- // Bugfix for the first running of the script on the page: wineSpending is not reduced by vineyard.
- if(firstRun) {
- // Get the vineyard.
- var vineyard = myGM.$('#locations .vineyard');
- // If a vineyard exists, reduce the wine spending.
- if(vineyard) {
- // Get the vineyard level.
- var level = vineyard.className.match(/level([0-9]*)/i)[1];
- // Reduce the wine spending.
- wineSpending = (wineSpending * (100 - level)) / 100;
- }
- }
- // Update the wood data.
- myGM.$(hourlyPrefix + types[0]).innerHTML = '<br>' + General.formatToIkaNumber(Math.floor(resource), true, true);
- myGM.$(dailyPrefix + types[0]).innerHTML = General.formatToIkaNumber(Math.floor(resource * 24), false);
- // Delete the last tradegood info.
- if(this.lastTradegood) {
- // Hourly.
- myGM.$(hourlyPrefix + types[this.lastTradegood]).innerHTML = '';
- // Daily.
- myGM.$(dailyPrefix + types[this.lastTradegood]).innerHTML = '';
- // Hide the daily tradegood info if it is not wine.
- if(this.lastTradegood != 1) myGM.$(dailyPrefix + 'Wrapper' + types[this.lastTradegood]).classList.add('invisible');
- }
- // Add the info if the city produces wine.
- if(producesWine) {
- // Hourly.
- myGM.$(hourlyPrefix + types[producedTradegood]).innerHTML = '<br>' + General.formatToIkaNumber(Math.floor(tradegood - wineSpending), true, true);
- // Daily.
- myGM.$(dailyPrefix + types[producedTradegood]).innerHTML = General.formatToIkaNumber(Math.floor((tradegood - wineSpending) * 24), false);
- // Add the info if the city doesn't produces wine.
- } else {
- // Hourly.
- myGM.$(hourlyPrefix + types[producedTradegood]).innerHTML = '<br>' + General.formatToIkaNumber(Math.floor(tradegood), true, true);
- myGM.$(hourlyPrefix + types[1]).innerHTML = '<br>' + General.formatToIkaNumber(Math.floor(-1 * wineSpending), true, true);
- // Daily.
- myGM.$(dailyPrefix + types[producedTradegood]).innerHTML = General.formatToIkaNumber(Math.floor(tradegood * 24), false);
- myGM.$(dailyPrefix + types[1]).innerHTML = General.formatToIkaNumber(Math.floor(-1 * wineSpending * 24), false);
- }
- // Show the daily tradegood info.
- myGM.$(dailyPrefix + 'Wrapper' + types[producedTradegood]).classList.remove('invisible');
- // Store the actual tradegood as last produced tradegood.
- this.lastTradegood = producedTradegood;
- },
- /**
- * Add a bar showing the status of the filling of the warehouse.
- */
- addCapacityInfo: function() {
- // If the info containers are already set, do nothing.
- if(myGM.$('#' + myGM.prefix + 'capacityInfowood')) {
- return;
- }
- // Set all resource types.
- var types = new Array('wood', 'wine', 'marble', 'glass', 'sulfur');
- // Has the capacity information a border?
- var hasBorder = myGM.getValue('resourceInfo_capacityStyle_hasBorder', true);
- // Loop over all resource types.
- for(var i = 0; i < types.length; i++) {
- // Add the hourly info.
- var wrapper = myGM.addElement('div', myGM.$('#resources_' + types[i]), 'capacityInfo' + types[i], hasBorder ? new Array('capacityInfo', 'border') : 'capacityInfo', null, true);
- myGM.addElement('div', wrapper, 'maxCapacity' + types[i], new Array('bar', 'yellow'), null, true);
- myGM.addElement('div', wrapper, 'warehouseCapacity' + types[i], new Array('bar', 'green'), null, true);
- myGM.addElement('div', wrapper, 'currentResource' + types[i], new Array('bar', 'red'), null, true);
- }
- // Update the resource information.
- this.updateCapacityInfo();
- // Add an event listener to update the shown resources.
- myGM.$('#cityResources').addEventListener('DOMSubtreeModified', ResourceInfo.updateCapacityInfo, false);
- },
- /**
- * Update the bar showing the status of the filling of the warehouse.
- */
- updateCapacityInfo: function() {
- // If the city is not owned by the player, stop the update.
- if(ika.model.isOwnCity != true) {
- return;
- }
- // Prefix for selection and user deifned settings.
- var prefix = '#' + myGM.prefix;
- var orientation = myGM.getValue('resourceInfo_capacityStyle_orientation', 'vertical');
- var showBranchOfficeRes = myGM.getValue('resourceInfo_showBranchRes', true);
- // If the info containers are not set, set them.
- if(!myGM.$(prefix + 'capacityInfowood')) {
- this.init();
- }
- // Set all resource types.
- var types = new Array('wood', 'wine', 'marble', 'glass', 'sulfur');
- // Get some needed data.
- var warehouseCapacity = new Array();
- var branchOfficeResources = new Array();
- var currentResources = new Array();
- warehouseCapacity.push(ika.model.maxResources.resource);
- branchOfficeResources.push(ika.model.branchOfficeResources.resource);
- currentResources.push(ika.model.currentResources.resource);
- for(var i = 1; i < types.length; i++) {
- warehouseCapacity.push(ika.model.maxResources[i]);
- branchOfficeResources.push(ika.model.branchOfficeResources[i]);
- currentResources.push(ika.model.currentResources[i]);
- }
- // Set the styles for all resources.
- for(var i = 0; i < types.length; i++) {
- var maxCapacity = myGM.$(prefix + 'maxCapacity' + types[i]);
- var curWarehouse = myGM.$(prefix + 'warehouseCapacity' + types[i]);
- var curResource = myGM.$(prefix + 'currentResource' + types[i]);
- var curTmp = (typeof(currentResources[i]) == 'string') ? General.getInt(currentResources[i]) : currentResources[i];
- var capTmp = (typeof(warehouseCapacity[i]) == 'string') ? General.getInt(warehouseCapacity[i]) : warehouseCapacity[i];
- var offTmp = (typeof(branchOfficeResources[i]) == 'string') ? General.getInt(branchOfficeResources[i]) : branchOfficeResources[i];
- var maxTmp = capTmp + offTmp;
- var curWarehousePercentage = showBranchOfficeRes ? (capTmp / maxTmp * 100) : 100;
- var curResourcePercentage = showBranchOfficeRes ? (curTmp / maxTmp * 100) : (curTmp / capTmp * 100);
- if(orientation == 'vertical') {
- maxCapacity.style.height = '100%';
- curWarehouse.style.height = curWarehousePercentage + '%';
- curResource.style.height = curResourcePercentage + '%';
- } else {
- maxCapacity.style.width = '100%';
- curWarehouse.style.width = curWarehousePercentage + '%';
- curResource.style.width = curResourcePercentage + '%';
- }
- }
- },
- /**
- * Adds links to access town hall, tradegood and sawmill to the resources menu.
- */
- addRessourceLinks: function() {
- // Set all tradegood types.
- var types = new Array('wine', 'marble', 'glass', 'sulfur');
- // Get the population and wood link.
- var population = myGM.$('#resources_population');
- var wood = myGM.$('#resources_wood');
- // Add the event listener.
- population.addEventListener('click', function() { win.ajaxHandlerCall('?view=city&dialog=townHall&cityId=' + ika.getModel().relatedCityData[ika.getModel().relatedCityData.selectedCity].id + '&position=0'); }, true);
- wood.addEventListener('click', function() { win.ajaxHandlerCall('?view=island&dialog=resource'); }, true);
- // Add the event listener to the tradegood links.
- for(var i = 0; i < types.length; i++) {
- var tradegood = myGM.$('#resources_' + types[i]);
- tradegood.addEventListener('click', function() { win.ajaxHandlerCall('?view=island&dialog=tradegood'); }, true);
- }
- // Add the styles.
- myGM.addStyle(
- "#resources_population:hover, #resources_wood:hover, #resources_wine:hover, #resources_marble:hover, #resources_glass:hover, #resources_sulfur:hover { text-shadow: 2px 2px 2px #666; cursor: pointer; color: #333; }",
- 'resourceLinks', true);
- }
- };
- /**
- * Functions for the member info.
- */
- MemberInfo = {
- /**
- * Storage for the highscore type.
- */
- type: '',
- /**
- * Storage for all actual member information.
- */
- data: null,
- /**
- * Init the member info.
- */
- init: function() {
- // Add the styles.
- myGM.addStyle(
- "#" + myGM.prefix + "resetInfo { float: right; margin-top: -6px; margin-right: 6px; } \
- .highscore .score span { float: right; text-align: right; width: 70px; } \
- .highscore .place span { float: right; text-align: right; width: 30px; } \
- .highscore th:nth-child(4) { width: 30% !important; } \
- .highscore th:nth-child(5) { width: 10% !important; } \
- #tab_highscore .centerButton { margin: 10px 0px; }",
- 'memberInfo', true
- );
- },
- /**
- * Starts the script.
- */
- show: function() {
- // Show the link for the info.
- this.addShowButton();
- // Show the info if the flag is set.
- if(myGM.getValue('memberInfo_infoLinkClicked', false)) {
- // Delete the flag.
- myGM.setValue('memberInfo_infoLinkClicked', false);
- // Show the information.
- this.showInfo();
- }
- },
- /**
- * Add a button for showing the inforation to the highscore.
- */
- addShowButton: function() {
- // Get the parent of the show button.
- var parent = myGM.$('#tab_highscore .centerButton');
- // Add the button to show the information.
- var btn = myGM.addElement('input', parent, 'showInfo', 'button');
- btn.type = 'button';
- btn.value = Language.$('memberInfo_show');
- // Add the event listener to the button.
- btn.addEventListener('click', EventHandling.memberInfo.clickShow, false);
- },
- /**
- * Add a button for resetting the inforation to the highscore.
- */
- addResetButton: function() {
- // Get the parent of the reset button.
- var parent = myGM.$('#tab_highscore .content p');
- // Add the reset button.
- var btn = myGM.addElement('input', parent, 'resetInfo', 'button');
- btn.type = 'button';
- btn.value = Language.$('memberInfo_reset');
- // Add the event listener to the button.
- btn.addEventListener('click', EventHandling.memberInfo.clickReset, false);
- },
- /**
- * Adds the time since the last reset to the highscore view.
- */
- addLastResetTime: function() {
- // Get the time since the last reset.
- var lastResetTime = myGM.getValue(General.getServerCode() + '_memberInfo_time_' + MemberInfo.type, 0);
- var diff = new Date() - lastResetTime;
- // Get the hours, days and minutes since the last reset.
- var d = Math.floor(diff / 86400000);
- diff = diff % 86400000;
- var h = Math.floor(diff / 3600000);
- diff = diff % 3600000;
- var m = Math.floor(diff / 60000);
- // Get the string of the last reset.
- var lastReset = lastResetTime ? (d + 'd ' + h + 'h ' + m + 'min') : Language.$('memberInfo_noReset');
- // Get the parent of the reset button.
- var parent = myGM.$('#tab_highscore .content p');
- // Add the reset button.
- var span = myGM.addElement('span', parent);
- span.innerHTML = '<br><span class="bold brown">' + Language.$('memberInfo_lastReset') + ' ' + lastReset + '</span>';
- },
- /**
- * Shows the information about the members in the highscore view.
- */
- showInfo: function() {
- // Set the highscore type.
- this.type = General.getSelectValue('js_highscoreType', true);
- // Storage for member information.
- var memberInfoData = {};
- // Storage for old member information.
- var memberInfoDataOld = myGM.getValue(General.getServerCode() + '_memberInfo_data_' + this.type, null);
- // Get the table rows of the ally members.
- var allyRows = myGM.$$('table.highscore tr.ownally');
- // Loop over all ally rows.
- for(var i = 0; i < allyRows.length; i++) {
- // Get the id of the ally member.
- var actionLink = myGM.$('.action a', allyRows[i]).href;
- var id = actionLink.match(/receiverId=([0-9]*)/i)[1];
- // Get score and place of the member and store it.
- memberInfoData[id] = {};
- memberInfoData[id]['place'] = General.getInt(myGM.$('.place', allyRows[i]).innerHTML);
- memberInfoData[id]['score'] = General.getInt(myGM.$('.score', allyRows[i]).innerHTML);
- // Get the difference in place and score.
- var placeDiff = myGM.addElement('span', myGM.$('.place', allyRows[i]));
- var scoreDiff = myGM.addElement('span', myGM.$('.score', allyRows[i]));
- // Show the difference in place and score.
- placeDiff.innerHTML += (memberInfoDataOld && memberInfoDataOld[id]) ? General.formatToIkaNumber(memberInfoDataOld[id]['place'] - memberInfoData[id]['place'], true, true) : '-';
- scoreDiff.innerHTML += (memberInfoDataOld && memberInfoDataOld[id]) ? General.formatToIkaNumber(memberInfoData[id]['score'] - memberInfoDataOld[id]['score'], true, true) : '-';
- }
- // Get the own table row.
- var ownRow = myGM.$('table.highscore tr.own');
- // Get the own score and place.
- memberInfoData['own'] = {};
- memberInfoData['own']['place'] = General.getInt(myGM.$('.place', ownRow).innerHTML);
- memberInfoData['own']['score'] = General.getInt(myGM.$('.score', ownRow).innerHTML);
- // Get the difference in place and score.
- var placeDiff = myGM.addElement('span', myGM.$('.place', ownRow));
- var scoreDiff = myGM.addElement('span', myGM.$('.score', ownRow));
- // Show the difference in place and score.
- placeDiff.innerHTML += (memberInfoDataOld && memberInfoDataOld['own']) ? General.formatToIkaNumber(memberInfoDataOld['own']['place'] - memberInfoData['own']['place'], true, true) : '-';
- scoreDiff.innerHTML += (memberInfoDataOld && memberInfoDataOld['own']) ? General.formatToIkaNumber(memberInfoData['own']['score'] - memberInfoDataOld['own']['score'], true, true) : '-';
- // Store the new member information for later use.
- this.data = memberInfoData;
- // Add the reset button.
- this.addResetButton();
- // Show the time of the last reset.
- this.addLastResetTime();
- }
- };
- /**
- * Functions for messages.
- */
- Message = {
- /**
- * Add a signature to each message.
- */
- addSignature: function() {
- // Storage for the signature text.
- var signature = '';
- // If the server signature should be used, get the server signature text.
- if(myGM.getValue('messageSignature_useServerSignature_' + General.getServerCode(), false)) {
- signature = myGM.getValue('messageSignature_serverSignature_' + General.getServerCode(), '');
- // Otherwise: get the global signature text.
- } else {
- signature = myGM.getValue('messageSignature_globalSignature', '');
- }
- // If a signature text is set, add it to the message.
- if(signature != '') {
- // Get the message area.
- var messageArea = myGM.$('#js_msgTextConfirm');
- // Get the message text and add the signature on the right placement.
- var text = messageArea.value;
- text = myGM.getValue('messageSignature_placementTop', true) ? ('\n\n' + signature + text) : (text + '\n\n' + signature);
- messageArea.value = text;
- // Focus the message area on top.
- messageArea.setSelectionRange(0,0);
- messageArea.focus();
- }
- },
- /**
- * Add a link for circular messages to the toolbar.
- */
- easyCircularMessage: function() {
- // Get the script toolbar.
- var scriptToolbar = myGM.$('#' + myGM.prefix + 'toolbar');
- // Add the message link wrapper.
- var circularMessageLinkWrapper = myGM.addElement('div', scriptToolbar, 'circularMessageLinkWrapper');
- // Prepare the message id, link, class and title.
- var id = myGM.prefix + 'circularMessageLink';
- var href = '?view=sendIKMessage&msgType=51&allyId=' + ika.getModel().avatarAllyId;
- var cl = href.match(/diplomacyAlly/) ? 'notSet' : '';
- var title = href.match(/diplomacyAlly/) ? Language.$('easyCircularMsg_getLink') : Language.$('easyCircularMsg_send');
- // Add the message link (workaround for ajaxHandlerCall).
- circularMessageLinkWrapper.innerHTML = '<a id="' + id + '" class="' + cl + '" href="' + href + '" title="' + title + '" onclick="ajaxHandlerCall(this.href); return false;"></a>';
- // Set the styles.
- myGM.addStyle(
- "#" + myGM.prefix + "circularMessageLinkWrapper { position: absolute; top: 5px; right: 70px; } \
- #" + myGM.prefix + "circularMessageLink { height: 9px; width: 13px; display: block; margin: 0px !important; background: url('skin/interface/icon_send_message.png') repeat scroll 0 0 transparent; } \
- #" + myGM.prefix + "circularMessageLink:hover { background-position: 0px -9px; } \
- #" + myGM.prefix + "circularMessageLink.notSet:hover { background-position: 0px -18px; }",
- 'easyCircularMessage', true);
- },
- /**
- * Set the style for the replaced urls.
- */
- setStyleForReplaceUrl: function() {
- // Add the style.
- myGM.addStyle(
- "." + myGM.prefix + "replacedUrl { font-weight: bold; font-style: italic; } \
- ." + myGM.prefix + "replacedUrl:hover { text-decoration: underline; cursor: pointer; }"
- );
- },
- /**
- * Make all URLs in messsages clickable. But with a security check.
- */
- replaceUrl: function() {
- // Get all message texts.
- var msgTexts = myGM.$$('.msgText');
- // Loop over all message texts.
- for(var i = 0; i < msgTexts.length; i++) {
- // Replace the URLs.
- var text = msgTexts[i].innerHTML;
- msgTexts[i].innerHTML = text.replace(/(?:^|\s)(http(s?)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/[^<\s]*)?)/g, ' <span class="' + myGM.prefix + 'replacedUrl" title="$1">$1</span> ');
- }
- // Get all replaced URLs.
- var replacedUrls = myGM.$$('.' + myGM.prefix + 'replacedUrl');
- // Loop over all replaced URLs.
- for(var i = 0; i < replacedUrls.length; i++) {
- // Add a click event to each replaced URL.
- replacedUrls[i].addEventListener('click', EventHandling.replacedUrl.click, true);
- }
- }
- };
- /**
- * Functions for cities.
- */
- City = {
- /**
- * Set the links for cities that are colonizing.
- */
- setColonizingLinks: function() {
- // Get all cities with level 0 (colonizing cities).
- var colonizingCities = myGM.$$('.level0');
- // Loop over the colonizing cities.
- for(var i = 0; i < colonizingCities.length; i++) {
- // Get the location id.
- var locationId = colonizingCities[i].id.replace(/\D/g, '');
- // Get the city id.
- var cityId = ika.getScreen().data.cities[locationId].id;
- // Set the city link.
- myGM.$('#js_cityLocation' + locationId + 'Link').href = '?view=cityDetails&destinationCityId=' + cityId;
- }
- }
- };
- /**
- * Functions for nice formatting of units.
- */
- UnitInfo = {
- /**
- * Add a link to the troops in town view to get a list for sharing.
- */
- addPopupLink: function() {
- var infoButton = myGM.addElement('input', myGM.$('#cityMilitary_c .buildingDescription'), null, 'button', new Array(['position', 'absolute'], ['top', '5px'], ['right', '20px']));
- infoButton.type = 'button';
- infoButton.value = Language.$('unitInfo_button');
- infoButton.addEventListener('click', EventHandling.unitInfo.click, true);
- },
- /**
- * Shows a popup with the unit information.
- */
- showPopup: function() {
- // Get information about the town.
- var selected = ika.getModel().relatedCityData[ika.getModel().relatedCityData.selectedCity];
- var townInfo = selected.name + ' ' + selected.coords;
- // Storage for output.
- var output = '<textarea readonly="readonly">';
- // Get the troops and ships.
- var troopList = this.getOutput('Units');
- var shipList = this.getOutput('Ships');
- // Add the troop list to the output, if filled.
- if(troopList.length > 0) {
- output += '===== ' + Language.$('unitInfo_units_label') + townInfo + ' =====' + troopList;
- // If there is also a shiplist, add a seperator.
- output += (shipList.length > 0) ? '\n\n' + '-'.repeat(85) + '\n\n' : '';
- }
- // Add the ship list to the output, if filled. {
- output += (shipList.length > 0) ? '===== ' + Language.$('unitInfo_ships_label') + townInfo + ' =====' + shipList : '';
- // Output should be in a textarea.
- output += '</textarea>';
- // Prepare the output.
- var text = {
- header: Language.$('unitInfo_header') + townInfo,
- body: output
- };
- // Show the output.
- var notificationId = myGM.notification(text);
- // Set the style for the textarea.
- myGM.addStyle(
- "#" + myGM.prefix + "notificationPanelBodyMContent" + notificationId + " textarea { width: 100%; height: 260px; resize: none;",
- 'unitInfoTextarea', true
- );
- // Add a the listener to select the information on focus.
- myGM.$('#' + myGM.prefix + 'notificationPanelBodyMContent' + notificationId + ' textarea').addEventListener('focus', function() { this.select(); }, false);
- },
- /**
- * Gets the units in a wrapper and returns them as a list.
- *
- * @param String id
- * The id of the tab.
- *
- * @return String
- * The value for this tab.
- */
- getOutput: function(id) {
- // Get the own units and store them.
- var ret = this.getOwnUnits(id);
- // Status of foreign troops.
- var foreignStatus = new Array('friends', 'enemies');
- // Get all wrapper for troops.
- var wrapper = myGM.$$('#tab' + id + ' .contentBox01h');
- // Loop over all wrappers.
- for(var i = 0; i < foreignStatus.length; i++) {
- // Get the foreign units for this status and store them.
- var foreignUnits = this.getForeignUnits(wrapper[i + 1], id, foreignStatus[i]);
- ret += (foreignUnits.length > 0) ? (((ret.length > 0) ? '\n' : '') + foreignUnits) : '';
- }
- // Return the output.
- return ret;
- },
- /**
- * Get the own units in the town.
- *
- * @param String id
- * The id of the tab.
- *
- * @return String
- * The list of own units.
- */
- getOwnUnits: function(id) {
- // Get the wrapper.
- var wrapper = myGM.$('#tab' + id + ' .contentBox01h');
- // Get the name and number cells.
- var nameCells = myGM.$$('.table01 .title_img_row th', wrapper);
- var numberCells = myGM.$$('.table01 .count td', wrapper);
- // Storage for the list.
- var list = '';
- // Add the units if their numer is not zero.
- for(var i = 0; i < nameCells.length; i++) {
- var name = nameCells[i].title;
- var number = General.getInt(numberCells[i].innerHTML);
- list += (number > 0) ? '\n' + name + ': ' + number : '';
- }
- // Get the headline.
- var headline = '\n--- ' + Language.$('unitInfo_' + id.toLowerCase() + '_own') + ' ---';
- // Return the list with headline if some units were found. Otherwise return an empty string.
- return (list.length > 0) ? (headline + list) : '';
- },
- /**
- * Get the foreign units in the town with the status.
- *
- * @param String wrapper
- * The wrapper which contains the foreign units.
- * @param String id
- * The id of the tab.
- * @param String status
- * The status of the units.
- *
- * @return String
- * The list of foreign units.
- */
- getForeignUnits: function(wrapper, id, status) {
- // Get the name cells and number rows.
- var nameCells = myGM.$$('.table01 .title_img_row th:not(:first-child)', wrapper);
- var numberRows = myGM.$$('.table01 tr:not(.title_img_row)', wrapper);
- // Distance between two belonging rows and storage for return value.
- var distance = numberRows.length / 2;
- var ret = '';
- // Iterate over all number rows.
- for(var i = 0; i < distance; i++) {
- // Get the number cells and the player name.
- var numberCells = myGM.$$('td:not(:first-child)', numberRows[i]).concat(myGM.$$('td:not(:first-child)', numberRows[i + distance]));
- var playerName = myGM.$('td a', numberRows[i]).innerHTML;
- // Storage for the list.
- var list = '';
- // Add the units if their numer is not zero.
- for(var k = 0; k < numberCells.length; k++) {
- var name = nameCells[k].title;
- var number = General.getInt(numberCells[k].innerHTML);
- list += (number > 0) ? '\n' + name + ': ' + number : '';
- }
- // Add the units with the player name to the list, if some units were found.
- list = ((list.length > 0) ? '\n* ' + playerName + ' *' : '') + list;
- ret += ((list.length > 0 && ret.length > 0) ? '\n' : '') + list;
- }
- // Get the headline.
- var headline = '\n--- ' + Language.$('unitInfo_' + id.toLowerCase() + '_' + status) + ' ---';
- // Return the list with headline if some units were found. Otherwise return an empty string.
- return (ret.length > 0) ? (headline + ret) : '';
- }
- };
- /**
- * The main function of the script.
- */
- function main() {
- // Init the myGM functions.
- myGM.init();
- // If the script was already executed, do nothing.
- if(myGM.$('#' + myGM.prefix + 'alreadyExecutedScript')) return;
- // Add the hint, that the script was already executed.
- var alreadyExecuted = myGM.addElement('input', myGM.$('#container'), 'alreadyExecutedScript');
- alreadyExecuted.type = 'hidden';
- // Init the language.
- Language.init();
- // Init the script.
- General.init();
- // Call the function to check for updates.
- Updater.init();
- // Call the function to enhance the view.
- EnhancedView.init();
- }
- // Call the main function of the script.
- setTimeout(main, 0);