您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Improve Diamond Hunt 2
当前为
- // ==UserScript==
- // @name DH2 Fixed
- // @namespace FileFace
- // @description Improve Diamond Hunt 2
- // @version 0.184.1
- // @author Zorbing
- // @license ISC; http://opensource.org/licenses/ISC
- // @grant none
- // @run-at document-start
- // @include http://www.diamondhunt.co/game.php
- // ==/UserScript==
- /**
- * ISC License (ISC)
- *
- * Copyright (c) 2017, Martin Boekhoff
- *
- * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby
- * granted, provided that the above copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Source: http://opensource.org/licenses/ISC
- */
- (function ()
- {
- 'use strict';
- var version = '0.184.1';
- /**
- * observer
- */
- var observer;
- (function (observer)
- {
- var observedKeys = new Map();
- function add(key, fn)
- {
- if (key instanceof Array)
- {
- for (var _i = 0, key_1 = key; _i < key_1.length; _i++)
- {
- var k = key_1[_i];
- add(k, fn);
- }
- }
- else
- {
- if (!observedKeys.has(key))
- {
- observedKeys.set(key, new Set());
- }
- observedKeys.get(key).add(fn);
- }
- return fn;
- }
- observer.add = add;
- function notify(key, oldValue)
- {
- var newValue = getGameValue(key);
- window[key] = newValue;
- if (observedKeys.has(key))
- {
- observedKeys.get(key).forEach(function (fn)
- {
- return fn(key, oldValue, newValue);
- });
- }
- }
- observer.notify = notify;
- function remove(key, fn)
- {
- if (key instanceof Array)
- {
- var ret = [];
- for (var _i = 0, key_2 = key; _i < key_2.length; _i++)
- {
- var k = key_2[_i];
- ret.push(remove(k, fn));
- }
- return ret;
- }
- if (!observedKeys.has(key))
- {
- return false;
- }
- return observedKeys.get(key).delete(fn);
- }
- observer.remove = remove;
- })(observer || (observer = {}));
- /**
- * global constants
- */
- var TIER_LEVELS = ['empty', 'sapphire', 'emerald', 'ruby', 'diamond'];
- var TIER_NAMES = ['Standard', 'Sapphire', 'Emerald', 'Ruby', 'Diamond'];
- var TIER_ITEMS = ['pickaxe', 'shovel', 'hammer', 'axe', 'rake', 'fishingRod', 'chisel'];
- var FURNACE_LEVELS = ['stone', 'bronze', 'iron', 'silver', 'gold'];
- var OVEN_LEVELS = ['bronze', 'iron', 'silver', 'gold'];
- var WAND_LEVELS = ['wooden', 'oak', 'willow', 'maple', 'stardust'];
- var OIL_STORAGE_SIZES = [10e3, 50e3, 100e3, 300e3, 600e3, 2e6];
- var HIDE_RECIPES = {
- 'drills':
- {
- max: 10
- }
- , 'crushers':
- {
- max: 10
- }
- , 'giantDrills':
- {
- max: 10
- }
- , 'excavators':
- {
- max: 10
- }
- , 'oilPipe':
- {
- max: 1
- }
- , 'pumpjacks':
- {
- max: 10
- }
- , 'rowBoat':
- {
- max: 1
- }
- , 'canoe':
- {
- max: 1
- }
- // thanks aguyd
- , 'bonemealBin':
- {
- extraKeys: ['boundFilledBonemealBin']
- , max: 1
- }
- , 'oilFactory':
- {
- max: 1
- }
- , 'brewingKit':
- {
- max: 1
- }
- , 'rocket':
- {
- max: 1
- }
- };
- var SMELTING_REQUIREMENTS = {
- 'glass':
- {
- sand: 1
- , oil: 10
- }
- , 'bronzeBar':
- {
- copper: 1
- , tin: 1
- , oil: 10
- }
- , 'ironBar':
- {
- iron: 1
- , oil: 100
- }
- , 'silverBar':
- {
- silver: 1
- , oil: 300
- }
- , 'goldBar':
- {
- gold: 1
- , oil: 1e3
- }
- , 'promethiumBar':
- {
- promethium: 1
- , charcoal: 1
- }
- };
- var PLANT_NAME = {
- '1': 'Dark Mushrooms'
- , '2': 'Red Mushrooms'
- , '3': 'Dotted Green Leafs'
- , '4': 'Green Leafs'
- , '5': 'Lime Leafs'
- , '6': 'Gold Leafs'
- , '7': 'Striped Gold Leafs'
- , '8': 'Crystal Leafs'
- , '9': 'Striped Crystal Leafs'
- , '10': 'Blewit Mushrooms'
- , '11': 'Snapegrass'
- , '12': 'Tree'
- , '13': 'Oak Tree'
- , '14': 'Wheat'
- , '15': 'Willow Tree'
- , '16': 'Grass'
- , '17': 'Maple Tree'
- , '18': 'Stardust Tree'
- , '19': 'Carrots'
- , '20': 'Tomatoes'
- , '21': 'Potatoes'
- };
- var SKILL_LIST = ['mining', 'crafting', 'woodcutting', 'farming', 'brewing', 'combat', 'fishing', 'cooking', 'magic'];
- var AREA_LIST = ['fields', 'forests', 'caves', 'volcano', 'northFields', 'hauntedMansion'];
- var AREA_NAMES = ['Fields', 'Forests', 'Caves', 'Volcano', 'Northern Fields', 'Haunted Mansion'];
- var MONSTER_NAMES = ['Chicken', 'Rat', 'Bee', 'Snake', 'Tree', 'Thief', 'Bear', 'Bat', 'Skeleton', 'Little Demon', 'Fire Bird', 'Healer', 'Zombie Goblin', 'Dead Tree', 'Ice Bird', 'Phantom', 'Ghost', 'The Death'];
- var FISH_XP = {
- 'rawShrimp': 50
- , 'rawSardine': 500
- , 'rawTuna': 3e3
- , 'rawSwordfish': 5e3
- , 'rawShark': 12e3
- };
- var BOAT_LIST = ['rowBoat', 'canoe'];
- var format;
- (function (format)
- {
- var UNITS = [
- {
- threshold: 10e3
- , factor: 1e3
- , token: 'k'
- }
- , {
- threshold: 1e6
- , factor: 1e6
- , token: 'M'
- }
- , {
- threshold: 1e9
- , factor: 1e9
- , token: 'B'
- }
- , {
- threshold: 1e12
- , factor: 1e12
- , token: 'T'
- }
- , {
- threshold: 1e15
- , factor: 1e15
- , token: 'Q'
- }];
- var TIME_STEPS = [
- {
- threshold: 1
- , name: 'second'
- , short: 'sec'
- , padp: 0
- }
- , {
- threshold: 60
- , name: 'minute'
- , short: 'min'
- , padp: 0
- }
- , {
- threshold: 3600
- , name: 'hour'
- , short: 'h'
- , padp: 1
- }
- , {
- threshold: 86400
- , name: 'day'
- , short: 'd'
- , padp: 2
- }];
- function zeroPadLeft(num)
- {
- return (num < 10 ? '0' : '') + num;
- }
- function ensureNumber(num)
- {
- return (typeof num === 'number' ? num : Number(num));
- }
- function number(num, shorten)
- {
- if (shorten === void 0)
- {
- shorten = false;
- }
- num = ensureNumber(num);
- if (shorten)
- {
- for (var i = UNITS.length - 1; i >= 0; i--)
- {
- var unit = UNITS[i];
- if (num >= unit.threshold)
- {
- return number(Math.round(num / unit.factor)) + unit.token;
- }
- }
- }
- return num.toLocaleString('en');
- }
- format.number = number;
- function numbersInText(text)
- {
- return text.replace(/\d(?:[\d',\.]*\d)?/g, function (numStr)
- {
- return number(numStr.replace(/\D/g, ''));
- });
- }
- format.numbersInText = numbersInText;
- // use time format established in DHQoL (https://greasyfork.org/scripts/16041-dhqol)
- function timer(timer, shorten)
- {
- if (shorten === void 0)
- {
- shorten = true;
- }
- if (typeof timer === 'string')
- {
- timer = parseInt(timer, 10);
- }
- timer = Math.max(timer, 0);
- var days = Math.floor(timer / 86400); // 24 * 60 * 60
- var hours = Math.floor((timer % 86400) / 3600); // 60 * 60
- var minutes = Math.floor((timer % 3600) / 60);
- var seconds = timer % 60;
- return (shorten && days === 0 ? '' : days + 'd ')
- + (shorten && days === 0 && hours === 0 ? '' : zeroPadLeft(hours) + ':')
- + zeroPadLeft(minutes) + ':'
- + zeroPadLeft(seconds);
- }
- format.timer = timer;
- function time2NearestUnit(time, long)
- {
- if (long === void 0)
- {
- long = false;
- }
- var step = TIME_STEPS[0];
- for (var i = TIME_STEPS.length - 1; i > 0; i--)
- {
- if (time >= TIME_STEPS[i].threshold)
- {
- step = TIME_STEPS[i];
- break;
- }
- }
- var factor = Math.pow(10, step.padp);
- var num = Math.round(time / step.threshold * factor) / factor;
- var unit = long ? step.name + (num === 1 ? '' : 's') : step.short;
- return num + ' ' + unit;
- }
- format.time2NearestUnit = time2NearestUnit;
- function min2Str(minutes)
- {
- if (typeof minutes === 'string')
- {
- minutes = parseInt(minutes, 10);
- }
- var m = minutes % 60;
- var h = Math.floor(minutes / 60);
- return (h > 0 ? h + ' hour' + (h == 1 ? '' : 's') + ' and ' : '')
- + m + ' minute' + (m == 1 ? '' : 's');
- }
- format.min2Str = min2Str;
- })(format || (format = {}));
- /**
- * general functions
- */
- function getStyle(elId)
- {
- var id = elId != null ? 'style-' + elId : null;
- var styleElement = id != null ? document.getElementById(id) : null;
- if (styleElement == null)
- {
- styleElement = document.createElement('style');
- if (id != null)
- {
- styleElement.id = id;
- }
- styleElement.type = 'text/css';
- document.head.appendChild(styleElement);
- }
- return styleElement;
- }
- function addStyle(styleCode, elId)
- {
- var styleElement = getStyle(elId);
- styleElement.innerHTML += styleCode;
- }
- function capitalize(str)
- {
- return str[0].toUpperCase() + str.substr(1);
- }
- function key2Name(key, lowerCase)
- {
- if (lowerCase === void 0)
- {
- lowerCase = false;
- }
- var name = key.replace(/[A-Z]/g, function (c)
- {
- return ' ' + (lowerCase ? c.toLowerCase() : c);
- });
- return lowerCase ? name : capitalize(name);
- }
- function split2Words(str, char)
- {
- if (char === void 0)
- {
- char = ' ';
- }
- return str.replace(/[A-Z]/g, char + '$&');
- }
- function getBoundKey(key)
- {
- return 'bound' + capitalize(key);
- }
- function getTierKey(key, tierLevel)
- {
- return TIER_LEVELS[tierLevel] + capitalize(key);
- }
- function getWikiaKey(key)
- {
- return key2Name(key.replace(/^bound-?|^special-case-/i, '').replace(/\d+[km]?$/i, ''))
- .replace(/^\s/, '').replace(/[ -]/g, '_')
- .replace(/^(?:Empty|Sapphire|Emerald|Ruby|Diamond|Raw|Uncooked|Filled)_/, '')
- .replace(/^(?:Bronze|Iron|Silver|Gold|Promethium|Runite)_(?!Bar)/, '')
- .replace(/^Npc_/, 'Monster_')
- .replace(/_(?:Unlocked|Quest)$/, '');
- }
- function getWikiaLink(key)
- {
- return 'http://diamondhuntonline.wikia.com/wiki/' + getWikiaKey(key);
- }
- function now()
- {
- return (new Date()).getTime();
- }
- function ensureTooltip(id, target)
- {
- var tooltipId = 'tooltip-' + id;
- var tooltipEl = document.getElementById(tooltipId);
- if (!tooltipEl)
- {
- tooltipEl = document.createElement('div');
- tooltipEl.id = tooltipId;
- tooltipEl.style.display = 'none';
- var tooltipList = document.getElementById('tooltip-list');
- tooltipList.appendChild(tooltipEl);
- }
- // ensure binded events to show the tooltip
- if (target.dataset.tooltipId == null)
- {
- target.dataset.tooltipId = tooltipId;
- window.$(target).bind(
- {
- mousemove: window.changeTooltipPosition
- , mouseenter: window.showTooltip
- , mouseleave: function (event)
- {
- var target = event.target;
- var parent = target.parentElement;
- // ensure tooltips inside an tooltip element is possible
- if (parent && !!parent.dataset.tooltipId)
- {
- window.showTooltip.call(parent, event);
- }
- else
- {
- window.hideTooltip(event);
- }
- }
- });
- }
- return tooltipEl;
- }
- var timeStr2Sec = (function ()
- {
- var unitFactors = {
- 'd': 24 * 60 * 60
- , 'h': 60 * 60
- , 'm': 60
- , 's': 1
- };
- return function timeStr2Sec(str)
- {
- return str
- .replace(/(\d+)([hms])/g, function (wholeMatch, num, unit)
- {
- return parseInt(num) * (unitFactors[unit] || 1) + '+';
- })
- .split('+')
- .map(function (s)
- {
- return parseInt(s, 10);
- })
- .filter(function (n)
- {
- return !isNaN(n);
- })
- .reduce(function (p, c)
- {
- return p + c;
- }, 0);
- };
- })();
- function getGameValue(key)
- {
- return window[key];
- }
- function getFurnaceLevel()
- {
- for (var i = FURNACE_LEVELS.length - 1; i >= 0; i--)
- {
- if (getGameValue(getBoundKey(FURNACE_LEVELS[i] + 'Furnace')) > 0)
- {
- return i;
- }
- }
- return -1;
- }
- function getFurnaceLevelName()
- {
- return FURNACE_LEVELS[getFurnaceLevel()] || '';
- }
- function getPrice(item)
- {
- var price = window.getPrice(item);
- if (typeof price === 'number')
- {
- return price;
- }
- var match = price.match(/(\d+)([kM])/);
- if (!match)
- {
- return parseInt(price, 10);
- }
- var FACTORS = {
- 'k': 1e3
- , 'M': 1e6
- };
- return parseInt(match[1], 10) * (FACTORS[match[2]] || 1);
- }
- /**
- * persistence store
- */
- var store;
- (function (store)
- {
- var oldPrefix = 'dh2-';
- var storePrefix = 'dh2.';
- function update(key, keepOldValue)
- {
- if (keepOldValue === void 0)
- {
- keepOldValue = true;
- }
- if (localStorage.hasOwnProperty(oldPrefix + key))
- {
- if (keepOldValue)
- {
- localStorage.setItem(storePrefix + key, localStorage.getItem(oldPrefix + key));
- }
- localStorage.removeItem(oldPrefix + key);
- }
- }
- var changeListener = new Map();
- function changeDetected(key, oldValue, newValue)
- {
- if (changeListener.has(key))
- {
- setTimeout(function ()
- {
- changeListener.get(key).forEach(function (fn)
- {
- return fn(key, oldValue, newValue);
- });
- });
- }
- }
- function watchFn(fnName)
- {
- var _fn = localStorage[fnName];
- localStorage[fnName] = function (key)
- {
- var args = [];
- for (var _i = 1; _i < arguments.length; _i++)
- {
- args[_i - 1] = arguments[_i];
- }
- var oldValue = localStorage.getItem(key);
- _fn.apply(localStorage, [key].concat(args));
- var newValue = localStorage.getItem(key);
- if (oldValue !== newValue)
- {
- changeDetected(key, oldValue, newValue);
- }
- };
- }
- watchFn('setItem');
- watchFn('removeItem');
- var _clear = localStorage.clear;
- localStorage.clear = function ()
- {
- var oldValues = new Map();
- for (var i = 0; i < localStorage.length; i++)
- {
- var key = localStorage.key(i);
- oldValues.set(key, localStorage.getItem(key));
- }
- _clear();
- for (var key in oldValues)
- {
- var newValue = localStorage.getItem(key);
- if (oldValues.get(key) !== newValue)
- {
- changeDetected(key, oldValues.get(key), newValue);
- }
- }
- };
- function addChangeListener(key, fn)
- {
- if (!changeListener.has(key))
- {
- changeListener.set(key, new Set());
- }
- changeListener.get(key).add(fn);
- }
- store.addChangeListener = addChangeListener;
- function removeChangeListener(key, fn)
- {
- if (changeListener.has(key))
- {
- changeListener.get(key).delete(fn);
- }
- }
- store.removeChangeListener = removeChangeListener;
- function get(key)
- {
- update(key);
- var value = localStorage.getItem(storePrefix + key);
- if (value != null)
- {
- try
- {
- return JSON.parse(value);
- }
- catch (e)
- {}
- }
- return value;
- }
- store.get = get;
- function has(key)
- {
- update(key);
- return localStorage.hasOwnProperty(storePrefix + key);
- }
- store.has = has;
- function remove(key)
- {
- update(key, false);
- localStorage.removeItem(storePrefix + key);
- }
- store.remove = remove;
- function set(key, value)
- {
- update(key, false);
- localStorage.setItem(storePrefix + key, JSON.stringify(value));
- }
- store.set = set;
- })(store || (store = {}));
- var settings;
- (function (settings)
- {
- settings.name = 'settings';
- var DIALOG_WIDTH = 450;
- var KEY;
- (function (KEY)
- {
- KEY[KEY["hideCraftingRecipes"] = 0] = "hideCraftingRecipes";
- KEY[KEY["hideUselessItems"] = 1] = "hideUselessItems";
- KEY[KEY["useNewChat"] = 2] = "useNewChat";
- KEY[KEY["colorizeChat"] = 3] = "colorizeChat";
- KEY[KEY["intelligentScrolling"] = 4] = "intelligentScrolling";
- KEY[KEY["showTimestamps"] = 5] = "showTimestamps";
- KEY[KEY["showIcons"] = 6] = "showIcons";
- KEY[KEY["showTags"] = 7] = "showTags";
- KEY[KEY["enableSpamDetection"] = 8] = "enableSpamDetection";
- KEY[KEY["showNotifications"] = 9] = "showNotifications";
- KEY[KEY["showEssencePopup"] = 10] = "showEssencePopup";
- KEY[KEY["wikiaLinks"] = 11] = "wikiaLinks";
- KEY[KEY["newXpAnimation"] = 12] = "newXpAnimation";
- KEY[KEY["amountSymbol"] = 13] = "amountSymbol";
- })(KEY = settings.KEY || (settings.KEY = {}));;
- var CFG = (_a = {}
- , _a[KEY.hideCraftingRecipes] = {
- name: 'Hide crafting recipes of finished items'
- , description: "Hides crafting recipes of:\n\t\t\t\t<ul style=\"margin: .5rem 0 0;\">\n\t\t\t\t\t<li>furnace, oil storage and oven recipes if they aren't better than the current level</li>\n\t\t\t\t\t<li>machines if the user has the maximum amount of this type (counts bound and unbound items)</li>\n\t\t\t\t\t<li>non-stackable items which the user already owns (counts bound and unbound items)</li>\n\t\t\t\t</ul>"
- , defaultValue: true
- }
- , _a[KEY.hideUselessItems] = {
- name: 'Hide useless items'
- , description: "Hides <em>unbound</em> items which may has been crafted accidentially and are of no use for the player:\n\t\t\t\t<ul style=\"margin: .5rem 0 0;\">\n\t\t\t\t\t<li>furnace, oil storage and oven recipes if they aren't better than the current level</li>\n\t\t\t\t\t<li>machines if the user has already bound the maximum amount of this type</li>\n\t\t\t\t\t<li>non-stackable items which the user has already bound</li>\n\t\t\t\t</ul>"
- , defaultValue: false
- }
- , _a[KEY.useNewChat] = {
- name: 'Use the new chat'
- , description: "Enables using the completely new chat with pm tabs, clickable links, clickable usernames to send a pm, intelligent scrolling and suggesting commands while typing"
- , defaultValue: true
- }
- , _a[KEY.colorizeChat] = {
- name: 'Colorize chat messages'
- , description: "Colorize chat messages according to a unique color for each user"
- , defaultValue: false
- , sub:
- {
- 'colorizer':
- {
- defaultValue: 0
- , label: ['Equally Distributed', 'Random (light colors)', 'Random (dark colors)']
- , options: ['equallyDistributed', 'random1', 'random2']
- }
- }
- }
- , _a[KEY.intelligentScrolling] = {
- name: 'Intelligent scrolling'
- , description: "Autoscroll gets disabled when you scroll up and gets enabled again when you scroll all the way down to the bottom of the chat."
- , defaultValue: true
- }
- , _a[KEY.showTimestamps] = {
- name: 'Show timestamps'
- , description: "Enables showing timestamps in chat"
- , defaultValue: true
- }
- , _a[KEY.showIcons] = {
- name: 'Show user-icons'
- , description: "Enables showing icons (formerly sigils) for each user in chat"
- , defaultValue: true
- }
- , _a[KEY.showTags] = {
- name: 'Show user-tags'
- , description: "Enables showing tags (Dev, Mod, Contributor) and colors for messages in chat"
- , defaultValue: true
- }
- , _a[KEY.enableSpamDetection] = {
- name: 'Enable spam detection'
- , description: "Enables simple spam detection"
- , defaultValue: true
- }
- , _a[KEY.showNotifications] = {
- name: 'Show browser notifications'
- , description: "Shows browser notifications for enabled events (click the little gear for more options)"
- , defaultValue: true
- , sub:
- {
- 'showType':
- {
- defaultValue: 0
- , label: ['only when window inactive', 'always']
- , options: ['whenInactive', 'always']
- }
- , 'smelting':
- {
- defaultValue: true
- , label: 'Smelting finishes'
- }
- , 'chopping':
- {
- defaultValue: true
- , label: 'A tree is fully grown'
- }
- , 'harvest':
- {
- defaultValue: true
- , label: 'A plant can be harvested'
- }
- , 'potionEffect':
- {
- defaultValue: true
- , label: 'A potion\'s effect ends'
- }
- , 'boatReturned':
- {
- defaultValue: true
- , label: 'The boat or canoe returns'
- }
- , 'heroReady':
- {
- defaultValue: true
- , label: 'The hero is fully recovered and ready to fight'
- }
- , 'itemsSold':
- {
- defaultValue: true
- , label: 'Items are sold on the market'
- }
- , 'pirate':
- {
- defaultValue: true
- , label: 'A pirate has found a treasure map'
- }
- , 'essence':
- {
- defaultValue: true
- , label: 'An essence was found'
- }
- , 'pm':
- {
- defaultValue: true
- , label: 'A private messages (pm) arrives'
- }
- , 'mention':
- {
- defaultValue: true
- , label: 'The username is mentioned in chat'
- }
- , 'keyword':
- {
- defaultValue: true
- , label: 'A keyword is mentioned in chat'
- }
- , 'serverMsg':
- {
- defaultValue: true
- , label: 'Server messages (like <em>Server is restarting...</em>)'
- }
- }
- }
- , _a[KEY.showEssencePopup] = {
- name: 'Show essence popup'
- , description: "Shown a popup (like the ones when a diamond is found or the server is restarting) for finding an essence"
- , defaultValue: false
- }
- , _a[KEY.wikiaLinks] = {
- name: 'Show wikia links'
- , description: "Show wikia links for every item on hover (the little icon in the upper left corner)"
- , defaultValue: true
- }
- , _a[KEY.newXpAnimation] = {
- name: 'New XP-gain animation'
- , description: "Show gained xp on top skill bar instead on the position of the mouse"
- , defaultValue: true
- }
- , _a[KEY.amountSymbol] = {
- name: 'Show \u00D7 on items'
- , description: "Show a tiny \u00D7-symbol before amount numbers of items"
- , defaultValue: true
- }
- , _a);
- var SETTINGS_TABLE_ID = 'dh2-settings';
- var SETTING_ID_PREFIX = 'dh2-setting-';
- var settings2Init = Object.keys(CFG);
- /**
- * settings
- */
- function toName(key, subKey)
- {
- var name = typeof key === 'string' ? key : KEY[key];
- if (subKey !== undefined)
- {
- return name + '.' + subKey;
- }
- return name;
- }
- function getStoreKey(key, subKey)
- {
- return 'setting.' + toName(key, subKey);
- }
- var observedSettings = new Map();
- var observedSubSettings = new Map();
- function observe(key, fn)
- {
- var n = toName(key);
- if (!observedSettings.has(n))
- {
- observedSettings.set(n, new Set());
- }
- observedSettings.get(n).add(fn);
- }
- settings.observe = observe;
- function observeSub(key, subKey, fn)
- {
- var n = toName(key, subKey);
- if (!observedSubSettings.has(n))
- {
- observedSubSettings.set(n, new Set());
- }
- observedSubSettings.get(n).add(fn);
- }
- settings.observeSub = observeSub;
- function unobserve(key, fn)
- {
- var n = toName(key);
- if (!observedSettings.has(n))
- {
- return false;
- }
- return observedSettings.get(n).delete(fn);
- }
- settings.unobserve = unobserve;
- function unobserveSub(key, subKey, fn)
- {
- var n = toName(key, subKey);
- if (!observedSubSettings.has(n))
- {
- return false;
- }
- return observedSubSettings.get(n).delete(fn);
- }
- settings.unobserveSub = unobserveSub;
- var settingsProxies = new Map();
- function get(key)
- {
- if (!CFG.hasOwnProperty(key))
- {
- return false;
- }
- if (settingsProxies.has(key))
- {
- var proxy = settingsProxies.get(key);
- return proxy.get(key);
- }
- var name = getStoreKey(key);
- return store.has(name) ? store.get(name) : CFG[key].defaultValue;
- }
- settings.get = get;
- function getSub(key, subKey)
- {
- if (!CFG.hasOwnProperty(key))
- {
- return null;
- }
- var name = getStoreKey(key, subKey);
- return store.has(name) ? store.get(name) : CFG[key].sub[subKey].defaultValue;
- }
- settings.getSub = getSub;
- function set(key, newValue)
- {
- if (!CFG.hasOwnProperty(key))
- {
- return;
- }
- var oldValue = get(key);
- var n = toName(key);
- if (settingsProxies.has(key))
- {
- var proxy = settingsProxies.get(key);
- proxy.set(key, oldValue, newValue);
- }
- else
- {
- store.set(getStoreKey(key), newValue);
- }
- if (oldValue !== newValue && observedSettings.has(n))
- {
- observedSettings.get(n).forEach(function (fn)
- {
- return fn(key, oldValue, newValue);
- });
- }
- }
- settings.set = set;
- function setSub(key, subKey, newValue)
- {
- if (!CFG.hasOwnProperty(key))
- {
- return;
- }
- var oldValue = getSub(key, subKey);
- var n = toName(key, subKey);
- store.set(getStoreKey(key, subKey), newValue);
- if (oldValue !== newValue && observedSubSettings.has(n))
- {
- observedSubSettings.get(n).forEach(function (fn)
- {
- return fn(key, subKey, oldValue, newValue);
- });
- }
- }
- settings.setSub = setSub;
- function getSubCfg(key)
- {
- if (!CFG.hasOwnProperty(key))
- {
- return;
- }
- return CFG[key].sub;
- }
- settings.getSubCfg = getSubCfg;
- function initSettingsStyle()
- {
- addStyle("\ntable.table-style1 tr:not([onclick])\n{\n\tcursor: initial;\n}\n#tab-container-profile h2.section-title\n{\n\tcolor: orange;\n\tline-height: 1.2rem;\n\tmargin-top: 2rem;\n}\n#tab-container-profile h2.section-title > span.note\n{\n\tfont-size: 0.9rem;\n}\n#" + SETTINGS_TABLE_ID + " tr.reload td:first-child::after\n{\n\tcontent: '*';\n\tfont-weight: bold;\n\tmargin-left: 3px;\n}\n#" + SETTINGS_TABLE_ID + " tr.sub td\n{\n\tposition: relative;\n}\n#" + SETTINGS_TABLE_ID + " tr.sub td button:last-child\n{\n\tmargin: -1px;\n\tposition: absolute;\n\tright: 0;\n}\n\n.ui-dialog-content > h2:first-child\n{\n\tmargin-top: 0;\n}\n\n.settings-container\n{\n\tlist-style: none;\n\tmargin: 5px 30px;\n\tpadding: 0;\n}\n.ui-dialog-content .settings-container\n{\n\tmargin: 5px 0;\n}\n.settings-container > li.setting\n{\n\tbackground-color: silver;\n\tborder: 1px solid black;\n\tborder-top-width: 0;\n\tdisplay: flex;\n}\n.settings-container > li.setting:first-child\n{\n\tborder-top-width: 1px;\n}\n.ui-dialog-content .settings-container > li.setting,\n.ui-dialog-content .settings-container > li.setting:hover\n{\n\tbackground-color: transparent;\n\tborder: 0;\n\tmargin: .25rem 0;\n}\n.settings-container > li.setting,\n.settings-container > li.setting *\n{\n\tcursor: pointer;\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n}\n.settings-container > li.setting:hover\n{\n\tbackground-color: gray;\n}\n.settings-container > li.setting > input[type=\"checkbox\"]\n{\n\tdisplay: none;\n}\n.settings-container > li.setting > label\n{\n\tdisplay: block;\n\tflex-grow: 1;\n\tpadding: .25rem .5rem;\n}\n.settings-container > li.setting > label.ui-checkboxradio-label\n{\n\ttext-align: left;\n}\n.settings-container > li.setting > label.ui-checkboxradio-label .ui-checkboxradio-icon-space\n{\n\tmargin-right: .25rem;\n}\n.settings-container > li.setting > input + label:not(.ui-checkboxradio-label)::before\n{\n\tbackground-image: url(images/icons/x.png);\n\tbackground-size: 20px;\n\tcontent: '';\n\tdisplay: inline-block;\n\theight: 20px;\n\tmargin: 0 .25rem;\n\twidth: 20px;\n\tvertical-align: middle;\n}\n.settings-container > li.setting > input:checked + label:not(.ui-checkboxradio-label)::before\n{\n\tbackground-image: url(images/icons/check.png);\n}\n.ui-dialog-content .settings-container > li.setting > label + button\n{\n\tmargin-left: -.2rem;\n\tz-index: 1;\n}\n.settings-container.sortable > li.setting > span.ui-icon.handle\n{\n\tfloat: left;\n\tmargin: 6px 10px;\n\tz-index: 10;\n}\n.settings-container > li.setting span.ui-selectmenu-button\n{\n\twidth: calc(100% - 2em - 2*3px + 2*.1em);\n}\n\t\t");
- }
- function getSettingId(key, subKey)
- {
- var name = toName(key) + (subKey !== undefined ? '-' + subKey : '');
- return SETTING_ID_PREFIX + split2Words(name, '-').toLowerCase();
- }
- function initSettingTable()
- {
- function insertAfter(newChild, oldChild)
- {
- var parent = oldChild.parentElement;
- if (oldChild.nextElementSibling == null)
- {
- parent.appendChild(newChild);
- }
- else
- {
- parent.insertBefore(newChild, oldChild.nextElementSibling);
- }
- }
- function getCheckImageSrc(value)
- {
- return 'images/icons/' + (value ? 'check' : 'x') + '.png';
- }
- var profileTable = document.getElementById('profile-toggleTable');
- if (!profileTable)
- {
- return;
- }
- var settingsHeader = document.createElement('h2');
- settingsHeader.className = 'section-title';
- settingsHeader.innerHTML = "Userscript \"DH2 Fixed\"<br>\n\t\t\t<span class=\"note\" style=\"display: none;\">(* changes require reloading the tab)</span>";
- var requiresReloadNote = settingsHeader.querySelector('.note');
- insertAfter(settingsHeader, profileTable);
- var settingsTable = document.createElement('table');
- settingsTable.id = SETTINGS_TABLE_ID;
- settingsTable.className = 'table-style1';
- settingsTable.width = '40%';
- settingsTable.innerHTML = "\n\t\t<tr style=\"background-color:grey;\">\n\t\t\t<th>Setting</th>\n\t\t\t<th>Enabled</th>\n\t\t</tr>\n\t\t";
- function addRowClickListener(row, key, settingId)
- {
- row.addEventListener('click', function ()
- {
- var newValue = !get(key);
- set(key, newValue);
- document.getElementById(settingId).src = getCheckImageSrc(newValue);
- });
- }
- function addSubClickListener(btn, dialog)
- {
- btn.addEventListener('click', function (event)
- {
- initJQueryDialog(dialog);
- event.stopPropagation();
- event.preventDefault();
- });
- }
- for (var _i = 0, settings2Init_1 = settings2Init; _i < settings2Init_1.length; _i++)
- {
- var k = settings2Init_1[_i];
- // convert it into a KEY
- var key = parseInt(k, 10);
- var setting = CFG[key];
- if (setting == null)
- {
- console.error('missing setting entry:', key, toName(key));
- continue;
- }
- var settingId = getSettingId(key);
- var row = settingsTable.insertRow(-1);
- row.classList.add('setting');
- if (setting.requiresReload)
- {
- row.classList.add('reload');
- requiresReloadNote.style.display = '';
- }
- row.setAttribute('onclick', '');
- row.innerHTML = "\n\t\t\t<td>" + setting.name + "</td>\n\t\t\t<td><img src=\"" + getCheckImageSrc(get(key)) + "\" id=\"" + settingId + "\" class=\"image-icon-20\"></td>\n\t\t\t";
- if (setting.sub)
- {
- row.classList.add('sub');
- var subBtn = document.createElement('button');
- subBtn.innerHTML = "<img src=\"images/icons/gearOff.gif\" class=\"image-icon-15\">";
- row.cells.item(0).appendChild(subBtn);
- var dialog = createSubSettingDialog(key);
- addSubClickListener(subBtn, dialog);
- }
- var tooltipEl = ensureTooltip(settingId, row);
- tooltipEl.innerHTML = setting.description;
- if (setting.requiresReload)
- {
- tooltipEl.innerHTML += "<span style=\"color: hsla(20, 100%, 50%, 1); font-size: .9rem; display: block; margin-top: 0.5rem;\">You have to reload the browser tab to apply changes to this setting.</span>";
- }
- addRowClickListener(row, key, settingId);
- }
- insertAfter(settingsTable, settingsHeader);
- }
- function initProxies()
- {
- var row = document.querySelector('tr[data-tooltip-id="tooltip-profile-removeCraftingFilter"]');
- if (row)
- {
- var valueCache_1 = getGameValue('profileRemoveCraftingFilter') != 1;
- settingsProxies.set(KEY.hideCraftingRecipes
- , {
- get: function (key)
- {
- return getGameValue('profileRemoveCraftingFilter') != 1;
- }
- , set: function (key, oldValue, newValue)
- {
- if (valueCache_1 != newValue)
- {
- row.click();
- valueCache_1 = newValue;
- }
- }
- });
- observer.add('profileRemoveCraftingFilter', function ()
- {
- set(KEY.hideCraftingRecipes, getGameValue('profileRemoveCraftingFilter') != 1);
- });
- }
- }
- var subDialog;
- (function (subDialog)
- {
- function defaultHandler(key, dialog)
- {
- var setting = CFG[key];
- var subSettings = setting.sub;
- var settingContainer = createSubSettingsContainer(key, subSettings);
- dialog.appendChild(settingContainer);
- }
- function colorizeChat(dialog)
- {
- defaultHandler(KEY.colorizeChat, dialog);
- }
- subDialog.colorizeChat = colorizeChat;
- function showNotifications(dialog)
- {
- dialog.appendChild(document.createTextNode('Show notifications\u2026'));
- defaultHandler(KEY.showNotifications, dialog);
- dialog.appendChild(document.createTextNode('Events for which notifications are shown:'));
- var ulNotifType = dialog.lastElementChild;
- var ulEvents = ulNotifType.cloneNode(false);
- while (ulNotifType.children.length > 1)
- {
- ulEvents.appendChild(ulNotifType.children.item(1));
- }
- dialog.appendChild(ulEvents);
- }
- subDialog.showNotifications = showNotifications;
- })(subDialog || (subDialog = {}));
- function createSubSettingDialog(key)
- {
- var settingId = getSettingId(key);
- var setting = CFG[key];
- var dialog = document.createElement('div');
- dialog.id = 'dialog-' + settingId;
- dialog.style.display = 'none';
- dialog.innerHTML = "<h2>" + setting.name + "</h2>";
- var name = toName(key);
- if (subDialog.hasOwnProperty(name))
- {
- subDialog[name](dialog);
- }
- else
- {
- console.warn('missing setting handler for "%s"', name);
- var todoEl = document.createElement('span');
- todoEl.textContent = 'TODO';
- dialog.appendChild(todoEl);
- }
- document.body.appendChild(dialog);
- return dialog;
- }
- function createSubSettingsContainer(parentKey, subSettings)
- {
- var settingsContainer = document.createElement('ul');
- settingsContainer.className = 'settings-container';
- function addCheckbox(listEl, subKey, id, setting)
- {
- var checkbox = document.createElement('input');
- checkbox.type = 'checkbox';
- checkbox.id = id;
- checkbox.name = id;
- checkbox.checked = getSub(parentKey, subKey);
- var label = document.createElement('label');
- label.htmlFor = id;
- label.innerHTML = setting.label;
- checkbox.addEventListener('change', function ()
- {
- return setSub(parentKey, subKey, checkbox.checked);
- });
- listEl.appendChild(checkbox);
- listEl.appendChild(label);
- }
- function addSelectmenu(listEl, subKey, id, setting)
- {
- var select = document.createElement('select');
- select.id = id;
- select.name = id;
- var options = setting.options;
- var selectedIndex = getSub(parentKey, subKey);
- for (var i = 0; i < options.length; i++)
- {
- var option = document.createElement('option');
- option.value = options[i];
- if (setting.label)
- {
- option.innerHTML = setting.label[i];
- }
- else
- {
- option.innerHTML = key2Name(options[i]);
- }
- option.selected = i == selectedIndex;
- select.appendChild(option);
- }
- select.addEventListener('change', function ()
- {
- return setSub(parentKey, subKey, select.selectedIndex);
- });
- listEl.appendChild(select);
- }
- var keyList = Object.keys(subSettings);
- var orderIndex = keyList.findIndex(function (k)
- {
- return subSettings[k].defaultValue instanceof Array;
- });
- var isSortable = orderIndex != -1;
- if (isSortable)
- {
- keyList = getSub(parentKey, keyList[orderIndex]);
- }
- for (var _i = 0, keyList_1 = keyList; _i < keyList_1.length; _i++)
- {
- var subKey = keyList_1[_i];
- var settingId = getSettingId(parentKey, subKey);
- var setting = subSettings[subKey];
- var listEl = document.createElement('li');
- listEl.classList.add('setting');
- if (isSortable)
- {
- listEl.dataset.subKey = subKey;
- var sortableIcon = document.createElement('span');
- sortableIcon.className = 'ui-icon ui-icon-arrowthick-2-n-s handle';
- listEl.appendChild(sortableIcon);
- }
- if (setting.options)
- {
- addSelectmenu(listEl, subKey, settingId, setting);
- }
- else
- {
- addCheckbox(listEl, subKey, settingId, setting);
- }
- settingsContainer.appendChild(listEl);
- }
- return settingsContainer;
- }
- function initJQueryDialog(dialog)
- {
- var $dialog = window.$(dialog);
- $dialog.dialog(
- {
- width: DIALOG_WIDTH + 'px'
- });
- $dialog.find('input[type="checkbox"]').checkboxradio()
- .next().children(':first-child').removeClass('ui-state-hover');
- $dialog.find('select').selectmenu(
- {
- change: function (event, ui)
- {
- var changeEvent = document.createEvent('HTMLEvents');
- changeEvent.initEvent('change', false, true);
- event.target.dispatchEvent(changeEvent);
- }
- });
- $dialog.find('.sortable').sortable(
- {
- handle: '.handle'
- , update: function (event, ui)
- {
- var newOrder = [];
- var children = event.target.children;
- for (var i = 0; i < children.length; i++)
- {
- var child = children[i];
- newOrder.push(child.dataset.subKey);
- }
- var updateEvent = new CustomEvent('sortupdate'
- , {
- detail: newOrder
- });
- event.target.dispatchEvent(updateEvent);
- }
- });
- return $dialog;
- }
- function createSettingsContainer(settingList)
- {
- var settingsContainer = document.createElement('ul');
- settingsContainer.className = 'settings-container';
- function addOpenDialogClickListener(el, dialog)
- {
- el.addEventListener('click', function (event)
- {
- initJQueryDialog(dialog);
- event.stopPropagation();
- event.preventDefault();
- });
- }
- function addChangeListener(key, checkbox)
- {
- checkbox.addEventListener('change', function ()
- {
- set(key, checkbox.checked);
- });
- }
- for (var _i = 0, settingList_1 = settingList; _i < settingList_1.length; _i++)
- {
- var key = settingList_1[_i];
- var settingId = getSettingId(key);
- var setting = CFG[key];
- var index = settings2Init.indexOf(key.toString());
- if (index != -1)
- {
- settings2Init.splice(index, 1);
- }
- var listEl = document.createElement('li');
- listEl.classList.add('setting');
- if (setting.requiresReload)
- {
- listEl.classList.add('reload');
- }
- var checkbox = document.createElement('input');
- checkbox.type = 'checkbox';
- checkbox.id = settingId;
- checkbox.checked = get(key);
- var label = document.createElement('label');
- label.htmlFor = settingId;
- label.textContent = setting.name;
- addChangeListener(key, checkbox);
- listEl.appendChild(checkbox);
- listEl.appendChild(label);
- if (setting.sub)
- {
- var moreBtn = document.createElement('button');
- moreBtn.innerHTML = "<img src=\"images/icons/gearOff.gif\" class=\"image-icon-20\" />";
- listEl.appendChild(moreBtn);
- var dialog = createSubSettingDialog(key);
- addOpenDialogClickListener(moreBtn, dialog);
- }
- settingsContainer.appendChild(listEl);
- var tooltipEl = ensureTooltip(settingId, listEl);
- tooltipEl.innerHTML = setting.description;
- if (setting.requiresReload)
- {
- tooltipEl.innerHTML += "<span style=\"color: hsla(20, 100%, 50%, 1); font-size: .9rem; display: block; margin-top: 0.5rem;\">You have to reload the browser tab to apply changes to this setting.</span>";
- }
- }
- return settingsContainer;
- }
- function initCraftingSettings()
- {
- var craftingItems = document.getElementById('tab-sub-container-crafting');
- if (!craftingItems)
- {
- return;
- }
- var br = craftingItems.nextElementSibling;
- var after = br.nextElementSibling;
- var parent = after.parentElement;
- var settingList = [KEY.hideCraftingRecipes, KEY.hideUselessItems];
- var settingsContainer = createSettingsContainer(settingList);
- parent.insertBefore(settingsContainer, after);
- }
- function initChatSettings()
- {
- var controlDiv = document.querySelector('#div-chat > div:first-child');
- if (!controlDiv)
- {
- return;
- }
- var btn = document.createElement('button');
- btn.textContent = 'Chat Settings';
- controlDiv.appendChild(btn);
- var dialog = document.createElement('div');
- dialog.id = 'dialog-chat-settings';
- dialog.style.display = 'none';
- dialog.innerHTML = "<h2>Chat Settings</h2>";
- var settingList = [KEY.useNewChat, KEY.colorizeChat, KEY.intelligentScrolling, KEY.showTimestamps, KEY.showIcons, KEY.showTags, KEY.enableSpamDetection];
- var settingsContainer = createSettingsContainer(settingList);
- dialog.appendChild(settingsContainer);
- document.body.appendChild(dialog);
- btn.addEventListener('click', function ()
- {
- initJQueryDialog(dialog);
- });
- }
- function init()
- {
- initProxies();
- initSettingsStyle();
- initCraftingSettings();
- initChatSettings();
- initSettingTable();
- }
- settings.init = init;
- var _a;
- })(settings || (settings = {}));
- /**
- * Code from https://github.com/davidmerfield/randomColor
- */
- var colorGenerator;
- (function (colorGenerator)
- {
- // seed to get repeatable colors
- var seed = null;
- var COLOR_NOT_FOUND = {
- hueRange: []
- , lowerBounds: []
- , saturationRange: []
- , brightnessRange: []
- };
- var COLOR_BOUNDS = {
- 'monochrome':
- {
- hueRange: []
- , lowerBounds: [
- [0, 0]
- , [100, 0]
- ]
- }
- , 'red':
- {
- hueRange: [-26, 18]
- , lowerBounds: [
- [20, 100]
- , [30, 92]
- , [40, 89]
- , [50, 85]
- , [60, 78]
- , [70, 70]
- , [80, 60]
- , [90, 55]
- , [100, 50]
- ]
- }
- , 'orange':
- {
- hueRange: [19, 46]
- , lowerBounds: [
- [20, 100]
- , [30, 93]
- , [40, 88]
- , [50, 86]
- , [60, 85]
- , [70, 70]
- , [100, 70]
- ]
- }
- , 'yellow':
- {
- hueRange: [47, 62]
- , lowerBounds: [
- [25, 100]
- , [40, 94]
- , [50, 89]
- , [60, 86]
- , [70, 84]
- , [80, 82]
- , [90, 80]
- , [100, 75]
- ]
- }
- , 'green':
- {
- hueRange: [63, 178]
- , lowerBounds: [
- [30, 100]
- , [40, 90]
- , [50, 85]
- , [60, 81]
- , [70, 74]
- , [80, 64]
- , [90, 50]
- , [100, 40]
- ]
- }
- , 'blue':
- {
- hueRange: [179, 257]
- , lowerBounds: [
- [20, 100]
- , [30, 86]
- , [40, 80]
- , [50, 74]
- , [60, 60]
- , [70, 52]
- , [80, 44]
- , [90, 39]
- , [100, 35]
- ]
- }
- , 'purple':
- {
- hueRange: [258, 282]
- , lowerBounds: [
- [20, 100]
- , [30, 87]
- , [40, 79]
- , [50, 70]
- , [60, 65]
- , [70, 59]
- , [80, 52]
- , [90, 45]
- , [100, 42]
- ]
- }
- , 'pink':
- {
- hueRange: [283, 334]
- , lowerBounds: [
- [20, 100]
- , [30, 90]
- , [40, 86]
- , [60, 84]
- , [80, 80]
- , [90, 75]
- , [100, 73]
- ]
- }
- };
- // shared color dictionary
- var colorDictionary = {};
- function defineColor(name, hueRange, lowerBounds)
- {
- var _a = lowerBounds[0]
- , sMin = _a[0]
- , bMax = _a[1];
- var _b = lowerBounds[lowerBounds.length - 1]
- , sMax = _b[0]
- , bMin = _b[1];
- colorDictionary[name] = {
- hueRange: hueRange
- , lowerBounds: lowerBounds
- , saturationRange: [sMin, sMax]
- , brightnessRange: [bMin, bMax]
- };
- }
- function loadColorBounds()
- {
- for (var name_1 in COLOR_BOUNDS)
- {
- defineColor(name_1, COLOR_BOUNDS[name_1].hueRange, COLOR_BOUNDS[name_1].lowerBounds);
- }
- }
- function randomWithin(min, max)
- {
- if (min === void 0)
- {
- min = 0;
- }
- if (max === void 0)
- {
- max = 0;
- }
- if (seed === null)
- {
- return Math.floor(min + Math.random() * (max + 1 - min));
- }
- else
- {
- // seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
- seed = (seed * 9301 + 49297) % 233280;
- var rnd = seed / 233280.0;
- return Math.floor(min + rnd * (max - min));
- }
- }
- function getColorInfo(hue)
- {
- // maps red colors to make picking hue easier
- if (hue >= 334 && hue <= 360)
- {
- hue -= 360;
- }
- for (var colorName in colorDictionary)
- {
- var color = colorDictionary[colorName];
- if (color.hueRange.length > 0
- && hue >= color.hueRange[0]
- && hue <= color.hueRange[1])
- {
- return colorDictionary[colorName];
- }
- }
- return COLOR_NOT_FOUND;
- }
- function getHueRange(colorInput)
- {
- var number = typeof colorInput === 'undefined' ? Number.NaN : colorInput;
- if (typeof number === 'string')
- {
- number = parseInt(number, 10);
- }
- if (colorInput && isNaN(number) && colorDictionary.hasOwnProperty(colorInput))
- {
- var color = colorDictionary[colorInput];
- if (color.hueRange.length > 0)
- {
- return color.hueRange;
- }
- }
- else if (!isNaN(number) && number < 360 && number > 0)
- {
- return [number, number];
- }
- return [0, 360];
- }
- function pickHue(options)
- {
- var hueRange = getHueRange(options.hue);
- var hue = randomWithin(hueRange[0], hueRange[1]);
- // instead of storing red as two seperate ranges, we group them, using negative numbers
- if (hue < 0)
- {
- return 360 + hue;
- }
- return hue;
- }
- function getSaturationRange(hue)
- {
- return getColorInfo(hue).saturationRange;
- }
- function pickSaturation(hue, options)
- {
- if (options.luminosity === 'random')
- {
- return randomWithin(0, 100);
- }
- if (options.hue === 'monochrome')
- {
- return 0;
- }
- var _a = getSaturationRange(hue)
- , sMin = _a[0]
- , sMax = _a[1];
- switch (options.luminosity)
- {
- case 'bright':
- sMin = 55;
- break;
- case 'dark':
- sMin = sMax - 10;
- break;
- case 'light':
- sMax = 55;
- break;
- }
- return randomWithin(sMin, sMax);
- }
- function getMinimumBrightness(H, S)
- {
- var lowerBounds = getColorInfo(H).lowerBounds;
- for (var i = 0; i < lowerBounds.length - 1; i++)
- {
- var _a = lowerBounds[i]
- , s1 = _a[0]
- , v1 = _a[1];
- var _b = lowerBounds[i + 1]
- , s2 = _b[0]
- , v2 = _b[1];
- if (S >= s1 && S <= s2)
- {
- var m = (v2 - v1) / (s2 - s1);
- var b = v1 - m * s1;
- return m * S + b;
- }
- }
- return 0;
- }
- function pickBrightness(H, S, options)
- {
- var bMin = getMinimumBrightness(H, S);
- var bMax = 100;
- switch (options.luminosity)
- {
- case 'dark':
- bMax = bMin + 20;
- break;
- case 'light':
- bMin = (bMax + bMin) / 2;
- break;
- case 'random':
- bMin = 0;
- bMax = 100;
- break;
- }
- return randomWithin(bMin, bMax);
- }
- function HSVtoHSL(hsv)
- {
- var h = hsv[0];
- var s = hsv[1] / 100;
- var v = hsv[2] / 100;
- var k = (2 - s) * v;
- return [
- h
- , Math.round(s * v / (k < 1 ? k : 2 - k) * 10000) / 100
- , k / 2 * 100
- ];
- }
- function HSVtoRGB(hsv)
- {
- // this doesn't work for the values of 0 and 360 here's the hacky fix
- var h = Math.min(Math.max(hsv[0], 1), 359);
- // Rebase the h,s,v values
- h = h / 360;
- var s = hsv[1] / 100;
- var v = hsv[2] / 100;
- var h_i = Math.floor(h * 6);
- var f = h * 6 - h_i;
- var p = v * (1 - s);
- var q = v * (1 - f * s);
- var t = v * (1 - (1 - f) * s);
- var r = 256;
- var g = 256;
- var b = 256;
- switch (h_i)
- {
- case 0:
- r = v;
- g = t;
- b = p;
- break;
- case 1:
- r = q;
- g = v;
- b = p;
- break;
- case 2:
- r = p;
- g = v;
- b = t;
- break;
- case 3:
- r = p;
- g = q;
- b = v;
- break;
- case 4:
- r = t;
- g = p;
- b = v;
- break;
- case 5:
- r = v;
- g = p;
- b = q;
- break;
- }
- return [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)];
- }
- function HSVtoHex(hsv)
- {
- function componentToHex(c)
- {
- var hex = c.toString(16);
- return hex.length == 1 ? '0' + hex : hex;
- }
- var rgb = HSVtoRGB(hsv);
- return '#' + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
- }
- function setFormat(hsv, options)
- {
- switch (options.format)
- {
- case 'hsvArray':
- return hsv;
- case 'hslArray':
- return HSVtoHSL(hsv);
- case 'hsl':
- var hsl = HSVtoHSL(hsv);
- return 'hsl(' + hsl[0] + ', ' + hsl[1] + '%, ' + hsl[2] + '%)';
- case 'hsla':
- var hslColor = HSVtoHSL(hsv);
- var alpha = options.alpha || Math.random();
- return 'hsla(' + hslColor[0] + ', ' + hslColor[1] + '%, ' + hslColor[2] + '%, ' + alpha + ')';
- case 'rgbArray':
- return HSVtoRGB(hsv);
- case 'rgb':
- var rgb = HSVtoRGB(hsv);
- return 'rgb(' + rgb.join(', ') + ')';
- case 'rgba':
- var rgbColor = HSVtoRGB(hsv);
- var alpha = options.alpha || Math.random();
- return 'rgba(' + rgbColor.join(', ') + ', ' + alpha + ')';
- case 'hex':
- default:
- return HSVtoHex(hsv);
- }
- }
- function generateColor(options)
- {
- // pick a hue (H)
- var H = pickHue(options);
- // use H to determine saturation (S)
- var S = pickSaturation(H, options);
- // use S and H to determine brightness (B)
- var B = pickBrightness(H, S, options);
- // return the HSB color in the desired format
- return setFormat([H, S, B], options);
- }
- function getRandom(options)
- {
- options = options ||
- {};
- seed = options.seed == null ? null : options.seed;
- // check if we need to generate multiple colors
- if (options.count !== null && options.count !== undefined)
- {
- var totalColors = options.count;
- var colors = [];
- options.count = null;
- while (totalColors > colors.length)
- {
- // Since we're generating multiple colors, the seed has to be incrememented.
- // Otherwise we'd just generate the same color each time...
- if (seed !== null)
- {
- seed += 1;
- }
- colors.push(generateColor(options));
- }
- options.count = totalColors;
- return colors;
- }
- return generateColor(options);
- }
- colorGenerator.getRandom = getRandom;
- var ColorInterval = (function ()
- {
- function ColorInterval(start, end)
- {
- this.start = start;
- this.end = end;
- this.left = null;
- this.right = null;
- this.value = null;
- }
- ColorInterval.prototype.getNextValue = function ()
- {
- if (this.value == null)
- {
- this.value = (this.start + this.end) / 2;
- return this.value;
- }
- if (this.left == null)
- {
- this.left = new ColorInterval(this.start, this.value);
- return this.left.getNextValue();
- }
- if (this.right == null)
- {
- this.right = new ColorInterval(this.value, this.end);
- return this.right.getNextValue();
- }
- if (this.left.getHeight() <= this.right.getHeight())
- {
- return this.left.getNextValue();
- }
- else
- {
- return this.right.getNextValue();
- }
- };
- ColorInterval.prototype.getHeight = function ()
- {
- return 1
- + (this.left == null ? 0 : this.left.getHeight())
- + (this.right == null ? 0 : this.right.getHeight());
- };
- return ColorInterval;
- }());
- var rootInterval = new ColorInterval(0, 360);
- function getEquallyDistributed()
- {
- return 'hsl(' + rootInterval.getNextValue() + ', 100%, 80%)';
- }
- colorGenerator.getEquallyDistributed = getEquallyDistributed;
- // populate the color dictionary
- loadColorBounds();
- })(colorGenerator || (colorGenerator = {}));
- /**
- * notifications
- */
- var notifications;
- (function (notifications)
- {
- notifications.name = 'notifications';
- function event(title, options)
- {
- if ((!options || options.whenActive !== true)
- && !document.hidden && document.hasFocus()
- && settings.getSub(settings.KEY.showNotifications, 'showType') !== 1)
- {
- return;
- }
- if (!settings.get(settings.KEY.showNotifications))
- {
- // notifications disabled: return stub notification
- return Promise.resolve(
- {
- close: function () {}
- });
- }
- if (!("Notification" in window))
- {
- return Promise.reject('Your browser does not support notifications.');
- }
- return Notification.requestPermission()
- .then(function (permission)
- {
- if (permission === 'granted')
- {
- var n_1 = new Notification(title, options);
- n_1.onclick = function (event)
- {
- if (options && options.autoFocus !== false)
- {
- window.focus();
- }
- if (options && options.autoClose !== false)
- {
- n_1.close();
- }
- if (options && options.onclick)
- {
- options.onclick(n_1, event);
- }
- };
- return Promise.resolve(n_1);
- }
- else
- {
- return Promise.reject('Notification permission denied');
- }
- });
- }
- notifications.event = event;
- function requestPermission()
- {
- if (settings.get(settings.KEY.showNotifications))
- {
- Notification.requestPermission();
- }
- }
- function init()
- {
- requestPermission();
- settings.observe(settings.KEY.showNotifications, function ()
- {
- return requestPermission();
- });
- }
- notifications.init = init;
- })(notifications || (notifications = {}));
- /**
- * process commands
- */
- var commands;
- (function (commands)
- {
- var XP_GAIN_KEY = 'xpGain';
- var MAX_XP_GAIN_HISTORY_LENGTH = 100;
- var IMAGE2SKILL = {
- // mining = #cc0000
- 'icons/pickaxe': 'mining'
- // crafting = #cc0000
- , 'icons/anvil': 'crafting'
- // woodcutting = cyan
- , 'icons/woodcutting': 'woodcutting'
- // farming = green
- , 'icons/watering-can': 'farming'
- // brewing = #800080
- , 'vialOfWater': 'brewing'
- , 'largeVialOfWater': 'brewing'
- , 'hugeVialOfWater': 'brewing'
- // combat = lime
- , 'icons/combat': 'combat'
- // magic = blue
- , 'icons/wizardhat': 'magic'
- // fishing = blue
- , 'tuna': 'fishing'
- // cooking = yellow
- , 'icons/cooking': 'cooking'
- };
- var xpGainHistory = store.has(XP_GAIN_KEY) ? store.get(XP_GAIN_KEY) :
- {};
- addStyle("\n.scroller.xp\n{\n\tfont-size: 18pt;\n\tposition: absolute;\n\ttext-align: center;\n}\n\t");
- function fishingXp2Fish(xp)
- {
- for (var fish in FISH_XP)
- {
- if (FISH_XP[fish] == xp)
- {
- return fish;
- }
- }
- return '';
- }
- function minutes2String(data)
- {
- return data.replace(/Your account has been running for: (\d+) minutes./, function (wholeMatch, minutes)
- {
- return 'Your account has been running for ' + format.min2Str(minutes) + '.';
- });
- }
- function processLoot(data)
- {
- if (!/^SM=Your boat found nothing\.$|^SHOW_LOOT_DIAG=/.test(data))
- {
- return false;
- }
- var loot = {
- type: 'loot'
- , title: ''
- , itemList: []
- };
- if (data.startsWith('SM='))
- {
- loot.title = 'Boat';
- loot.emptyText = 'Your boat found nothing.';
- }
- else if (data.startsWith('SHOW_LOOT_DIAG='))
- {
- var split = data.substr('SHOW_LOOT_DIAG='.length).split('~');
- loot.title = split[0];
- for (var i = 1; i < split.length; i += 2)
- {
- loot.itemList.push(
- {
- key: split[i]
- , amount: Number(split[i + 1])
- });
- }
- }
- log.add(loot);
- return true;
- }
- var XP_GAIN_REGEX = /^ST=([^~]+)\.png~([^~]+)~\+(\d+)\s*xp$/;
- var animationQueue = {};
- function queueXpAnimation(skill, cell, color, xpAmount)
- {
- if (!settings.get(settings.KEY.newXpAnimation))
- {
- return;
- }
- animationQueue[skill] = animationQueue[skill] || [];
- animationQueue[skill].push(
- {
- cell: cell
- , color: color
- , xpAmount: xpAmount
- });
- if (animationQueue[skill].length === 1)
- {
- nextAnimation(skill);
- }
- }
- function nextAnimation(skill)
- {
- var entry = animationQueue[skill][0];
- if (!entry || !settings.get(settings.KEY.newXpAnimation))
- {
- return;
- }
- var cell = entry.cell
- , color = entry.color
- , xpAmount = entry.xpAmount;
- var rect = cell.getBoundingClientRect();
- var $el = window.$("<div class=\"scroller xp\" style=\"color: " + color + "; left: " + (rect.left + 50) + "px; top: " + (document.body.scrollTop + rect.top) + "px; width: " + (rect.width - 2 * 20 - 50) + "px;\">+" + format.number(xpAmount) + "</div>")
- .appendTo('body');
- // ensure the existence of $el, so the complete-function can be called instantly if the window is hidden
- $el
- .animate(
- {
- top: '-=15px'
- }
- , {
- duration: 1500
- , easing: 'easeOutQuad'
- , complete: function ()
- {
- animationQueue[skill].shift();
- nextAnimation(skill);
- }
- })
- .fadeOut(
- {
- duration: 2500
- , queue: false
- , complete: function ()
- {
- return $el.remove();
- }
- });
- }
- function processXpGain(data)
- {
- var match = data.match(XP_GAIN_REGEX);
- if (!match)
- {
- return false;
- }
- var icon = match[1];
- var skill = IMAGE2SKILL[icon] || '';
- var color = match[2];
- var xpAmount = Number(match[3]);
- var cell = document.getElementById('top-bar-level-td-' + skill);
- if (!cell)
- {
- console.debug('match (no cell found):', match);
- return false;
- }
- var entry = {
- time: now()
- , amount: xpAmount
- };
- if (skill == 'fishing')
- {
- var caughtFish = fishingXp2Fish(xpAmount);
- log.add(
- {
- type: 'fish'
- , fish: caughtFish
- });
- }
- // save the xp event
- var list = xpGainHistory[skill] || [];
- list.push(entry);
- xpGainHistory[skill] = list.slice(-MAX_XP_GAIN_HISTORY_LENGTH);
- store.set(XP_GAIN_KEY, xpGainHistory);
- if (settings.get(settings.KEY.newXpAnimation))
- {
- queueXpAnimation(skill, cell, color, xpAmount);
- }
- return true;
- }
- function processLevelUp(data)
- {
- if (!data.startsWith('LVL_UP='))
- {
- return false;
- }
- var skill = data.substr('LVL_UP='.length);
- var xp = getGameValue(skill + 'Xp');
- var oldLvl = window.getLevel(xp);
- log.add(
- {
- type: 'lvlup'
- , skill: skill
- , newLevel: oldLvl + 1
- });
- return true;
- }
- function processCombat(data)
- {
- var match = data.match(/^STHS=(.+)~(.+)~(\d+)~img-(.+)~(melee|heal)$/);
- if (!match)
- {
- return false;
- }
- // keep track of different battles and add the data to the current battle
- log.add(
- {
- type: 'combat'
- , monsterId: window.fightMonsterId
- , parts: [
- {
- type: match[5]
- , who: match[4]
- , number: Number(match[3])
- }]
- });
- return true;
- }
- function processEnergy(data)
- {
- var match = data.match(/^ST=steak\.png~orange~\+([\d',]+)$/);
- if (!match)
- {
- return false;
- }
- log.add(
- {
- type: 'energy'
- , energy: Number(match[1].replace(/\D/g, ''))
- });
- return true;
- }
- function processHeat(data)
- {
- var match = data.match(/^ST=icons\/fire\.png~red~\+([\d',]+)$/);
- if (!match)
- {
- return false;
- }
- log.add(
- {
- type: 'heat'
- , heat: Number(match[1].replace(/\D/g, ''))
- });
- return true;
- }
- var RUNNING_ACCOUNT_STR = 'Your account has been running for:';
- function formatData(data)
- {
- if (data.startsWith('STHS=')
- || data.startsWith('STE=')
- || data.startsWith('SM=')
- || data.startsWith('ST=')
- || data.startsWith('SHOW_LOOT_DIAG='))
- {
- if (data.indexOf(RUNNING_ACCOUNT_STR) != -1)
- {
- data = minutes2String(data);
- }
- data = format.numbersInText(data);
- }
- return data;
- }
- commands.formatData = formatData;
- function process(data)
- {
- // prepare for logging events in an activity log
- if (processLoot(data))
- {
- return;
- }
- else if (processXpGain(data))
- {
- // return undefined to let the original function be called
- return settings.get(settings.KEY.newXpAnimation) ? null : void 0;
- }
- else if (processLevelUp(data))
- {
- return;
- }
- else if (processCombat(data))
- {
- return;
- }
- else if (processEnergy(data))
- {
- return;
- }
- else if (processHeat(data))
- {
- return;
- }
- else if (data.startsWith('SM='))
- {}
- else if (data.startsWith('STHS=') || data.startsWith('STE=') || data.startsWith('ST='))
- {}
- // notifications for this kind of message: "SM=An update has been scheduled for today."
- if (data.startsWith('SM='))
- {
- if (settings.getSub(settings.KEY.showNotifications, 'serverMsg'))
- {
- var msg = data.substr(3)
- .replace(/<br\s*\/?>/g, '\n')
- .replace(/<img src='images\/(.+?)\.png'.+?\/?> (\d+)/g, function (wholeMatch, key, amount)
- {
- return format.number(amount) + ' ' + split2Words(key) + ', ';
- })
- .replace(/(\s)\1+/g, '$1')
- .replace(/, $/, '')
- .replace(/<.+?>/g, '');
- notifications.event('Message from server'
- , {
- body: minutes2String(msg)
- });
- }
- }
- return;
- }
- commands.process = process;
- })(commands || (commands = {}));
- /**
- * log activities and stuff
- */
- var log;
- (function (log)
- {
- log.name = 'log';
- var LOG_KEY = 'activityLog';
- var MAX_LOG_SIZE = 100;
- var logList = store.has(LOG_KEY) ? store.get(LOG_KEY) : [];
- var currentCombat = null;
- var currentCombatEl = null;
- var logEl;
- function createLi(entry)
- {
- var entryEl = document.createElement('li');
- entryEl.dataset.time = (new Date(entry.time || 0)).toLocaleString();
- entryEl.dataset.type = entry.type;
- return entryEl;
- }
- function appendLi(entryEl)
- {
- if (logEl.firstChild)
- {
- logEl.insertBefore(entryEl, logEl.firstChild);
- }
- else
- {
- logEl.appendChild(entryEl);
- }
- }
- function setGenericEntry(entry)
- {
- var el = createLi(entry);;
- el.innerHTML = typeof entry.data === 'string' ? entry.data : JSON.stringify(entry.data);
- appendLi(el);
- }
- function setLootEntry(entry)
- {
- var el = createLi(entry);
- var header = document.createElement('h1');
- header.className = 'container-title';
- header.textContent = entry.title;
- el.appendChild(header);
- var itemContainer = document.createElement('span');
- if (entry.itemList.length === 0)
- {
- itemContainer.innerHTML = "<span class=\"dialogue-loot\">" + entry.emptyText + "</span>";
- }
- else
- {
- for (var _i = 0, _a = entry.itemList; _i < _a.length; _i++)
- {
- var item = _a[_i];
- var itemEl = document.createElement('span');
- itemEl.className = 'dialogue-loot';
- itemEl.innerHTML = "<img src=\"" + item.key + "\" class=\"image-icon-50\"> " + item.amount;
- itemContainer.appendChild(itemEl);
- itemContainer.appendChild(document.createTextNode(' '));
- }
- }
- el.appendChild(itemContainer);
- appendLi(el);
- }
- function setFishEntry(entry)
- {
- var el = createLi(entry);
- el.innerHTML = "You caught a " + key2Name(entry.fish, true) + ".";
- appendLi(el);
- }
- function setEnergyEntry(entry)
- {
- var el = createLi(entry);
- el.innerHTML = "Your hero gained " + format.number(entry.energy) + " energy.";
- appendLi(el);
- }
- function setHeatEntry(entry)
- {
- var el = createLi(entry);
- el.innerHTML = "You added " + format.number(entry.heat) + " heat to your oven.";
- appendLi(el);
- }
- function setLevelUpEntry(entry)
- {
- var el = createLi(entry);
- el.innerHTML = "You advanced your " + entry.skill + "-skill to level " + entry.newLevel + ".";
- appendLi(el);
- }
- function setCombatEntry(entry)
- {
- var created = currentCombatEl == null;
- if (currentCombatEl == null)
- {
- currentCombatEl = createLi(entry);
- }
- var heroHeal = 0;
- var heroDamage = 0;
- var monsterHeal = 0;
- var monsterDamage = 0;
- for (var i = 0; i < entry.parts.length; i++)
- {
- var part = entry.parts[i];
- if (part.who == 'hero')
- {
- if (part.type == 'heal')
- {
- heroHeal += part.number;
- }
- else
- {
- heroDamage += part.number;
- }
- }
- else
- {
- if (part.type == 'heal')
- {
- monsterHeal += part.number;
- }
- else
- {
- monsterDamage += part.number;
- }
- }
- }
- // TODO: names for monster id
- var monsterName = MONSTER_NAMES[entry.monsterId] || '(' + (entry.monsterId % 3 + 1) + ')';
- var areaId = Math.floor(entry.monsterId / 3);
- var areaName = AREA_NAMES[areaId] || '(' + (areaId + 1) + ')';
- currentCombatEl.innerHTML = "<h2>Combat against " + monsterName + " in " + areaName + "</h2>\n\t\t<div>Hero: <span style=\"color: green;\">+" + heroHeal + "</span> <span style=\"color: red;\">-" + heroDamage + "</span></div>\n\t\t<div>Monster: <span style=\"color: green;\">+" + monsterHeal + "</span> <span style=\"color: red;\">-" + monsterDamage + "</span></div>";
- if (created)
- {
- appendLi(currentCombatEl);
- }
- }
- var entryType2Fn = {
- 'loot': setLootEntry
- , 'fish': setFishEntry
- , 'energy': setEnergyEntry
- , 'heat': setHeatEntry
- , 'lvlup': setLevelUpEntry
- , 'combat': setCombatEntry
- };
- function updateLog(entry)
- {
- if (!logEl)
- {
- return;
- }
- if (entry.type && entryType2Fn.hasOwnProperty(entry.type))
- {
- entryType2Fn[entry.type](entry);
- }
- else
- {
- setGenericEntry(entry);
- }
- }
- function add(entry)
- {
- if (!entry.time)
- {
- entry.time = now();
- }
- if (entry.type == 'combat')
- {
- if (currentCombat == null)
- {
- currentCombat = entry;
- }
- else
- {
- (_a = currentCombat.parts).push.apply(_a, entry.parts);
- }
- entry = currentCombat;
- }
- logList.push(entry);
- logList = logList.slice(-MAX_LOG_SIZE);
- store.set(LOG_KEY, logList);
- updateLog(entry);
- var _a;
- }
- log.add = add;
- function init()
- {
- addStyle("\n#show-activity-log\n{\n\tdisplay: none;\n}\nbody\n{\n\toverflow-y: scroll;\n}\n#activity-log-label\n{\n\tcolor: pink;\n\tcursor: pointer;\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n}\n#activity-log-overlay\n{\n\tbackground-color: transparent;\n\tcolor: transparent;\n\tpointer-events: none;\n\tposition: fixed;\n\tbottom: 0;\n\tleft: 0;\n\ttop: 0;\n\tright: 0;\n\ttransition: background-color .3s ease-out;\n\tz-index: 1000;\n}\n#show-activity-log:checked ~ #activity-log-overlay\n{\n\tbackground-color: rgba(0, 0, 0, 0.4);\n\tpointer-events: all;\n}\n#activity-log\n{\n\tbackground-color: white;\n\tcolor: black;\n\tlist-style: none;\n\tmargin: 0;\n\toverflow-y: scroll;\n\tpadding: .4rem .8rem;\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\ttransform: translateX(100%);\n\ttransition: transform .3s ease-out;\n\tmin-width: 15rem;\n\twidth: 40%;\n\tmax-width: 30rem;\n\tz-index: 1000;\n}\n#show-activity-log:checked ~ #activity-log\n{\n\ttransform: translateX(0%);\n}\n#activity-log::before\n{\n\tcontent: 'Activity Log';\n\tdisplay: block;\n\tfont-size: 1rem;\n\tfont-weight: bold;\n\tmargin-bottom: 0.8rem;\n}\n#activity-log:empty::after\n{\n\tcontent: 'Activities will be listed here.';\n}\n#activity-log li\n{\n\tborder: 1px solid gray;\n\tborder-radius: .2rem;\n\tmargin: .2rem 0;\n\tpadding: .4rem .8rem;\n}\n#activity-log li::before\n{\n\tcolor: gray;\n\tcontent: attr(data-time);\n\tdisplay: block;\n\tfont-size: 0.8rem;\n\tmargin: -4px 0 4px -4px;\n}\n\t\t");
- // add new tab "Activity Log"
- var checkboxId = 'show-activity-log';
- var activityLogLabel = document.createElement('label');
- activityLogLabel.id = 'activity-log-label';
- activityLogLabel.htmlFor = checkboxId;
- activityLogLabel.textContent = 'Activity Log';
- newTopbar.addTabEntry(activityLogLabel);
- var checkbox = document.createElement('input');
- checkbox.id = checkboxId;
- checkbox.type = 'checkbox';
- checkbox.style.display = 'none';
- document.body.insertBefore(checkbox, document.body.firstChild);
- var label = document.createElement('label');
- label.id = 'activity-log-overlay';
- label.htmlFor = checkboxId;
- document.body.appendChild(label);
- logEl = document.createElement('ul');
- logEl.id = 'activity-log';
- document.body.appendChild(logEl);
- // add all stored elements
- logList.forEach(function (e)
- {
- return updateLog(e);
- });
- observer.add('fightMonsterId', function (key, oldValue, newValue)
- {
- if (newValue === 0)
- {
- currentCombat = null;
- currentCombatEl = null;
- }
- });
- }
- log.init = init;
- })(log || (log = {}));
- /**
- * game events
- */
- var gameEvents;
- (function (gameEvents)
- {
- gameEvents.name = 'gameEvents';
- // min time difference between two notifications with the same title (10 seconds)
- var MIN_TIME_DIFFERENCE = 10;
- gameEvents.enabled = {
- smelting: true
- , chopping: true
- , harvest: true
- , boat: true
- , battle: true
- , brewing: true
- , market: true
- };
- var lastTimestamp = new Map();
- function notifyTabClickable(title, body, icon, tabKey, whenActive)
- {
- if (whenActive === void 0)
- {
- whenActive = false;
- }
- var now = (new Date).getTime();
- var timeDiff = now - (lastTimestamp.get(title) || 0);
- if (timeDiff < MIN_TIME_DIFFERENCE * 1e3)
- {
- return;
- }
- var promise = notifications.event(title
- , {
- body: body
- , icon: 'images/' + icon
- , whenActive: whenActive
- , onclick: function ()
- {
- var tabNames = tabKey.split('.');
- window.openTab(tabNames[0]);
- if (tabNames.length > 1)
- {
- window.openSubTab(tabNames[1]);
- }
- }
- });
- if (promise)
- {
- lastTimestamp.set(title, now);
- }
- }
- function observeTimer(k, fn)
- {
- observer.add(k, function (key, oldValue, newValue)
- {
- if (oldValue > 0 && newValue == 0)
- {
- fn(key, oldValue, newValue);
- }
- });
- }
- function smelting()
- {
- observeTimer('smeltingPercD', function (key, oldValue, newValue)
- {
- if (!gameEvents.enabled.smelting || !settings.getSub(settings.KEY.showNotifications, 'smelting'))
- {
- return;
- }
- notifyTabClickable('Hot topic', 'Your smelting has finished.', getFurnaceLevelName() + 'Furnace.png', 'crafting');
- });
- }
- function chopping()
- {
- observer.add([
- 'treeStage1'
- , 'treeStage2'
- , 'treeStage3'
- , 'treeStage4'
- , 'treeStage5'
- , 'treeStage6'
- ], function (key, oldValue, newValue)
- {
- if (!gameEvents.enabled.chopping || !settings.getSub(settings.KEY.showNotifications, 'chopping'))
- {
- return;
- }
- if (newValue == 4)
- {
- notifyTabClickable('Wood you be mine?', 'One or more of your trees are fully grown and can be chopped.', 'icons/woodcutting.png', 'woodcutting');
- }
- });
- }
- function harvest()
- {
- observer.add([
- 'farmingPatchStage1'
- , 'farmingPatchStage2'
- , 'farmingPatchStage3'
- , 'farmingPatchStage4'
- , 'farmingPatchStage5'
- , 'farmingPatchStage6'
- ], function (key, oldValue, newValue)
- {
- if (!gameEvents.enabled.harvest || !settings.getSub(settings.KEY.showNotifications, 'harvest'))
- {
- return;
- }
- if (newValue == 4)
- {
- notifyTabClickable('Green thumb', 'One or more of your crops is ready for harvest.', 'icons/watering-can.png', 'farming');
- }
- else if (newValue > 4)
- {
- notifyTabClickable('I didn\'t plant this', 'One or more of your crops died.', 'icons/watering-can.png', 'farming');
- }
- });
- }
- function boat()
- {
- observeTimer([
- 'rowBoatTimer'
- , 'canoeTimer'
- ], function (k, oldValue, newValue)
- {
- if (!gameEvents.enabled.boat || !settings.getSub(settings.KEY.showNotifications, 'boatReturned'))
- {
- return;
- }
- var key = k.replace(/Timer$/, '');
- notifyTabClickable('Fishy business', 'Your ' + split2Words(key).toLowerCase() + ' returned from its trip.', key + '.png', 'combat');
- });
- }
- function battle()
- {
- observeTimer('combatGlobalCooldown', function (key, oldValue, newValue)
- {
- if (!gameEvents.enabled.battle || !settings.getSub(settings.KEY.showNotifications, 'heroReady'))
- {
- return;
- }
- notifyTabClickable('Ready to work', 'Your hero is eager to fight.', 'icons/combat.png', 'combat');
- });
- }
- function brewing()
- {
- observeTimer([
- 'barPotionTimer'
- , 'seedPotionTimer'
- , 'stardustPotionTimer'
- , 'superStardustPotionTimer'
- ], function (key, oldValue, newValue)
- {
- if (!gameEvents.enabled.brewing || !settings.getSub(settings.KEY.showNotifications, 'potionEffect'))
- {
- return;
- }
- var potionKey = key.replace(/Timer$/, '');
- if (getGameValue(potionKey) > 0)
- {
- notifyTabClickable('Cheers!', 'You can drink another ' + split2Words(potionKey) + '.', key.replace(/Timer$/, '') + '.png', 'brewing');
- }
- });
- }
- function market()
- {
- var _refreshMarketSlot = window.refreshMarketSlot;
- window.refreshMarketSlot = function (offerId, itemName, amount, price, collectText, slotId, timeLeft)
- {
- if (gameEvents.enabled.market && settings.getSub(settings.KEY.showNotifications, 'itemsSold') && collectText > 0)
- {
- if (amount > 0)
- {
- notifyTabClickable('Ka-ching', 'You\'ve sold some ' + split2Words(itemName).toLowerCase() + ' to the market.', 'icons/shop.png', 'playermarket');
- }
- else
- {
- notifyTabClickable('Sold out', 'You\'ve sold all ' + split2Words(itemName).toLowerCase() + ' to the market.', 'icons/shop.png', 'playermarket');
- }
- }
- _refreshMarketSlot(offerId, itemName, amount, price, collectText, slotId, timeLeft);
- };
- }
- function gameValues()
- {
- observer.add('treasureMap', function (key, oldValue, newValue)
- {
- if (settings.getSub(settings.KEY.showNotifications, 'pirate') && oldValue > newValue)
- {
- notifyTabClickable('Arrrr!', 'Your pirate found a treasure map.', 'treasureMap.png', 'items');
- }
- });
- observer.add('essence', function (key, oldValue, newValue)
- {
- if (oldValue < newValue)
- {
- var diff = newValue - oldValue;
- var num = ['one', 'two', 'three'][diff - 1] || diff;
- var text = 'You found ' + num + ' essence' + (diff > 1 ? 's' : '') + '.';
- if (settings.get(settings.KEY.showEssencePopup))
- {
- window.confirmDialogue(400, text, 'Close', '', '');
- }
- if (settings.getSub(settings.KEY.showNotifications, 'essence'))
- {
- notifyTabClickable('Essence of Life', text, 'essence.png', 'combat.spells');
- }
- }
- });
- }
- function init()
- {
- smelting();
- chopping();
- harvest();
- boat();
- battle();
- brewing();
- market();
- gameValues();
- }
- gameEvents.init = init;
- })(gameEvents || (gameEvents = {}));
- /**
- * hide crafting recipes of lower tiers or of maxed machines
- */
- var crafting;
- (function (crafting)
- {
- crafting.name = 'crafting';
- /**
- * hide crafted recipes
- */
- function setRecipeVisibility(key, visible)
- {
- var recipeRow = document.getElementById('crafting-' + key);
- if (recipeRow)
- {
- recipeRow.style.display = (!settings.get(settings.KEY.hideCraftingRecipes) || visible) ? '' : 'none';
- }
- }
- function hideLeveledRecipes(max, getKey, init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var keys2Observe = [];
- var maxLevel = 0;
- for (var i = max - 1; i >= 0; i--)
- {
- var level = i + 1;
- var key = getKey(i);
- var boundKey = getBoundKey(key);
- keys2Observe.push(key);
- keys2Observe.push(boundKey);
- if (getGameValue(key) > 0 || getGameValue(boundKey) > 0)
- {
- maxLevel = Math.max(maxLevel, level);
- }
- setRecipeVisibility(key, level > maxLevel);
- }
- if (init)
- {
- observer.add(keys2Observe, function ()
- {
- return hideLeveledRecipes(max, getKey, false);
- });
- }
- }
- function hideToolRecipe(key, init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var emptyKey = getTierKey(key, 0);
- var keys2Observe = [emptyKey];
- var hasTool = getGameValue(emptyKey) > 0;
- for (var i = 0; i < TIER_LEVELS.length; i++)
- {
- var boundKey = getBoundKey(getTierKey(key, i));
- hasTool = hasTool || getGameValue(boundKey) > 0;
- keys2Observe.push(boundKey);
- }
- setRecipeVisibility(emptyKey, !hasTool);
- if (init)
- {
- observer.add(keys2Observe, function ()
- {
- return hideToolRecipe(key, false);
- });
- }
- }
- function hideRecipe(key, hideInfo, init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var maxValue = typeof hideInfo.max === 'function' ? hideInfo.max() : hideInfo.max;
- var boundKey = getBoundKey(key);
- var unbound = getGameValue(key);
- var bound = getGameValue(boundKey);
- var extra = (hideInfo.extraKeys || []).map(function (k)
- {
- return getGameValue(k);
- }).reduce(function (p, c)
- {
- return p + c;
- }, 0);
- setRecipeVisibility(key, (bound + unbound + extra) < maxValue);
- if (init)
- {
- observer.add([key, boundKey], function ()
- {
- return hideRecipe(key, hideInfo, false);
- });
- }
- }
- /**
- * hide useless items
- */
- function setItemVisibility(key, visible)
- {
- var itemBox = document.getElementById('item-box-' + key);
- if (itemBox)
- {
- itemBox.style.display = getGameValue(key) > 0 && (!settings.get(settings.KEY.hideUselessItems) || visible) ? '' : 'none';
- }
- }
- function hideLeveledItems(max, getKey, init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var keys2Observe = [];
- var maxLevel = 0;
- for (var i = max - 1; i >= 0; i--)
- {
- var level = i + 1;
- var key = getKey(i);
- var boundKey = getBoundKey(key);
- keys2Observe.push(key);
- keys2Observe.push(boundKey);
- if (getGameValue(boundKey) > 0)
- {
- maxLevel = Math.max(maxLevel, level);
- }
- setItemVisibility(key, level > maxLevel);
- }
- if (init)
- {
- observer.add(keys2Observe, function ()
- {
- return hideLeveledItems(max, getKey, false);
- });
- }
- }
- function hideItem(key, hideInfo, init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var maxValue = typeof hideInfo.max === 'function' ? hideInfo.max() : hideInfo.max;
- var boundKey = getBoundKey(key);
- var bound = getGameValue(boundKey);
- var extra = (hideInfo.extraKeys || []).map(function (k)
- {
- return getGameValue(k);
- }).reduce(function (p, c)
- {
- return p + c;
- }, 0);
- setItemVisibility(key, (bound + extra) < maxValue);
- if (init)
- {
- observer.add([key, boundKey], function ()
- {
- return hideItem(key, hideInfo, false);
- });
- }
- }
- function init()
- {
- function processRecipes(init)
- {
- if (init === void 0)
- {
- init = false;
- }
- // furnace
- hideLeveledRecipes(FURNACE_LEVELS.length, function (i)
- {
- return FURNACE_LEVELS[i] + 'Furnace';
- }, init);
- // oil storage
- hideLeveledRecipes(OIL_STORAGE_SIZES.length, function (i)
- {
- return 'oilStorage' + (i + 1);
- }, init);
- // oven recipes
- hideLeveledRecipes(OVEN_LEVELS.length, function (i)
- {
- return OVEN_LEVELS[i] + 'Oven';
- }, init);
- // tools
- for (var _i = 0, TIER_ITEMS_1 = TIER_ITEMS; _i < TIER_ITEMS_1.length; _i++)
- {
- var tool = TIER_ITEMS_1[_i];
- hideToolRecipe(tool, init);
- }
- // other stuff
- for (var key in HIDE_RECIPES)
- {
- hideRecipe(key, HIDE_RECIPES[key], init);
- }
- if (init)
- {
- settings.observe(settings.KEY.hideCraftingRecipes, function ()
- {
- return processRecipes(false);
- });
- }
- }
- processRecipes(true);
- var _processCraftingTab = window.processCraftingTab;
- window.processCraftingTab = function ()
- {
- var reinit = !!window.refreshLoadCraftingTable;
- _processCraftingTab();
- if (reinit)
- {
- processRecipes(false);
- }
- };
- function processItems(init)
- {
- if (init === void 0)
- {
- init = false;
- }
- // furnace
- hideLeveledItems(FURNACE_LEVELS.length, function (i)
- {
- return FURNACE_LEVELS[i] + 'Furnace';
- }, init);
- // oil storage
- hideLeveledItems(OIL_STORAGE_SIZES.length, function (i)
- {
- return 'oilStorage' + (i + 1);
- }, init);
- // oven recipes
- hideLeveledItems(OVEN_LEVELS.length, function (i)
- {
- return OVEN_LEVELS[i] + 'Oven';
- }, init);
- // other stuff
- for (var key in HIDE_RECIPES)
- {
- hideItem(key, HIDE_RECIPES[key], init);
- }
- if (init)
- {
- settings.observe(settings.KEY.hideUselessItems, function ()
- {
- return processItems(false);
- });
- }
- }
- processItems(true);
- }
- crafting.init = init;
- })(crafting || (crafting = {}));
- /**
- * improve item boxes
- */
- var itemBoxes;
- (function (itemBoxes)
- {
- itemBoxes.name = 'itemBoxes';
- function hideNumberInItemBox(key, setVisibility)
- {
- if (setVisibility === void 0)
- {
- setVisibility = false;
- }
- var itemBox = document.getElementById('item-box-' + key);
- if (!itemBox)
- {
- return;
- }
- var numberElement = itemBox.lastElementChild;
- if (!numberElement)
- {
- return;
- }
- if (setVisibility)
- {
- numberElement.style.visibility = 'hidden';
- }
- else
- {
- numberElement.style.display = 'none';
- }
- }
- function addSpan2ItemBox(key)
- {
- hideNumberInItemBox(key);
- var itemBox = document.getElementById('item-box-' + key);
- if (!itemBox)
- {
- return;
- }
- var span = document.createElement('span');
- itemBox.appendChild(span);
- return span;
- }
- function setOilPerSecond(span, oil)
- {
- span.innerHTML = "+ " + format.number(oil) + " L/s <img src=\"images/oil.png\" class=\"image-icon-20\" style=\"margin-top: -2px;\">";
- }
- // show capacity of furnace
- function addFurnaceCaption()
- {
- for (var i = 0; i < FURNACE_LEVELS.length; i++)
- {
- var key = FURNACE_LEVELS[i] + 'Furnace';
- var boundKey = getBoundKey(key);
- var capacitySpan = addSpan2ItemBox(boundKey);
- if (capacitySpan)
- {
- capacitySpan.className = 'capacity';
- capacitySpan.textContent = 'Capacity: ' + format.number(window.getFurnaceCapacity(boundKey), true);
- }
- }
- // charcoal foundry
- var foundryCapacitySpan = addSpan2ItemBox('charcoalFoundry');
- if (foundryCapacitySpan)
- {
- foundryCapacitySpan.className = 'capacity';
- foundryCapacitySpan.textContent = 'Capacity: 100';
- }
- }
- // show oil cap of oil storage
- function addOilStorageCaption()
- {
- for (var i = 0; i < OIL_STORAGE_SIZES.length; i++)
- {
- var key = 'oilStorage' + (i + 1);
- var capSpan = addSpan2ItemBox(getBoundKey(key));
- if (capSpan)
- {
- capSpan.className = 'oil-cap';
- capSpan.textContent = 'Oil cap: ' + format.number(OIL_STORAGE_SIZES[i], true);
- }
- }
- }
- // show oil per second
- function addOilCaption()
- {
- var handheldOilSpan = addSpan2ItemBox('handheldOilPump');
- if (handheldOilSpan)
- {
- setOilPerSecond(handheldOilSpan, 1 * window.miner);
- observer.add('miner', function ()
- {
- return setOilPerSecond(handheldOilSpan, 1 * window.miner);
- });
- }
- var oilPipeSpan = addSpan2ItemBox('boundOilPipe');
- if (oilPipeSpan)
- {
- setOilPerSecond(oilPipeSpan, 50);
- }
- // add number of workers as caption to oil factory
- var workerSpan = addSpan2ItemBox('boundOilFactory');
- if (workerSpan)
- {
- var setCaption_1 = function ()
- {
- return workerSpan.textContent = 'Workers: ' + format.number(window.oilFactoryCheapWorkers, true);
- };
- setCaption_1();
- observer.add('oilFactoryCheapWorkers', function ()
- {
- return setCaption_1();
- });
- }
- }
- function addWandCaption()
- {
- for (var i = 0; i < WAND_LEVELS.length; i++)
- {
- var level = WAND_LEVELS[i];
- var key = level + 'Wand';
- var wandSpan = addSpan2ItemBox(key);
- if (wandSpan)
- {
- wandSpan.textContent = capitalize(level) + ' Wand';
- }
- }
- }
- function addVariousCaptions()
- {
- var key2Name = {
- 'emptyAnvil': 'Anvil'
- , 'tap': 'Tree Tap'
- , 'farmer': 'Farmer'
- , 'gardener': 'Gardener'
- , 'planter': 'Planter'
- , 'boundBrewingKit': 'Brewing Kit'
- , 'cooksBook': 'Cooks Book'
- , 'cooksPage': 'Cooks Page'
- , 'combatDropTable': 'Loot Table'
- , 'magicBook': 'Spell Book'
- };
- for (var key in key2Name)
- {
- var span = addSpan2ItemBox(key);
- if (span)
- {
- span.textContent = key2Name[key];
- }
- }
- }
- // show current tier
- function addTierCaption()
- {
- for (var _i = 0, TIER_ITEMS_2 = TIER_ITEMS; _i < TIER_ITEMS_2.length; _i++)
- {
- var tierItem = TIER_ITEMS_2[_i];
- for (var i = 0; i < TIER_LEVELS.length; i++)
- {
- var key = getTierKey(tierItem, i);
- var toolKey = tierItem == 'rake' ? key : getBoundKey(key);
- var tierSpan = addSpan2ItemBox(toolKey);
- if (tierSpan)
- {
- tierSpan.className = 'tier';
- tierSpan.textContent = TIER_NAMES[i];
- }
- }
- }
- }
- var boatKeys = ['rowBoat', 'canoe'];
- var boatTimerKeys = boatKeys.map(function (k)
- {
- return k + 'Timer';
- });
- function checkBoat(span, timerKey, init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var isInTransit = getGameValue(timerKey) > 0;
- var otherInTransit = boatTimerKeys.some(function (k)
- {
- return k != timerKey && getGameValue(k) > 0;
- });
- span.textContent = isInTransit ? 'In transit' : 'Ready';
- span.style.visibility = otherInTransit ? 'hidden' : '';
- if (init)
- {
- observer.add(boatTimerKeys, function ()
- {
- return checkBoat(span, timerKey, false);
- });
- }
- }
- // show boat progress
- function addBoatCaption()
- {
- for (var i = 0; i < boatKeys.length; i++)
- {
- var span = addSpan2ItemBox(getBoundKey(boatKeys[i]));
- if (span)
- {
- checkBoat(span, boatTimerKeys[i], true);
- }
- }
- }
- // show bonemeal
- function addBonemealCaption()
- {
- var noBonemealSpan = addSpan2ItemBox('boundBonemealBin');
- if (!noBonemealSpan)
- {
- return;
- }
- noBonemealSpan.textContent = 'Bonemeal: 0';
- var bonemealSpan = addSpan2ItemBox('boundFilledBonemealBin');
- if (!bonemealSpan)
- {
- return;
- }
- bonemealSpan.dataset.itemDisplay = 'bonemeal';
- bonemealSpan.textContent = format.number(window.bonemeal);
- var captionSpan = document.createElement('span');
- captionSpan.textContent = 'Bonemeal: ';
- bonemealSpan.parentElement.insertBefore(captionSpan, bonemealSpan);
- }
- function warningBeforeSellingGems()
- {
- var _sellNPCItemDialogue = window.sellNPCItemDialogue;
- window.sellNPCItemDialogue = function (item, amount)
- {
- if (item == 'sapphire' || item == 'emerald' || item == 'ruby' || item == 'diamond' || item == 'bloodDiamond')
- {
- var itemName = key2Name(amount == 1 ? item : item.replace(/y$/, 'ie') + 's', true);
- if (amount == 0
- || !window.confirm('Gems are precious and rare. Please consider carefully:\nDo you really want to sell ' + amount + ' ' + itemName + '?'))
- {
- return;
- }
- }
- else if (item == 'logs' || item == 'oakLogs' || item == 'willowLogs' || item == 'mapleLogs' || item == 'stardustLogs' || item == 'ancientLogs')
- {
- var itemName = key2Name(amount == 1 ? item.replace(/s$/, '') : item, true);
- if (amount == 0
- || !window.confirm('Logs are time consuming to collect. Please consider carefully:\nDo you really want to sell ' + amount + ' ' + itemName + '?'))
- {
- return;
- }
- }
- _sellNPCItemDialogue(item, amount);
- };
- }
- function addWikiaLinks()
- {
- var WIKIA_CLASS = 'wikia-links';
- addStyle("\n." + WIKIA_CLASS + " .item-box\n{\n\tposition: relative;\n}\n.item-box > .wikia-link\n{\n\tbackground: black url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"30\" height=\"30\" viewBox=\"-2 -2 26 27\"><defs><linearGradient id=\"a\" x1=\"0%\" x2=\"63.85%\" y1=\"100%\" y2=\"32.54%\"><stop stop-color=\"#94D11F\" offset=\"0%\"/><stop stop-color=\"#09D3BF\" offset=\"100%\"/></linearGradient></defs><path fill=\"url(#a)\" fill-rule=\"evenodd\" d=\"M10.18 16.8c0 .2-.05.46-.26.67l-.8.7-7.38-6.95v-2.7l8.1 7.62c.12.12.33.36.33.66zm11.2-8.1v2.53l-9.15 8.86a.67.67 0 0 1-.5.2.73.73 0 0 1-.5-.2l-.85-.77 11-10.62zm-6.97 4.5l-2.53 2.43-8.04-7.67a2 2 0 0 1 0-2.9l2.53-2.43 8.04 7.67c.84.8.84 2.1 0 2.9zm-1.5-6.68L15.56 4c.4-.4.94-.6 1.52-.6.57 0 1.1.2 1.52.6l2.72 2.6-4.16 3.98-1.52-1.45-2.73-2.6zm10.18-.4l-6-5.8L17 .2l-.14.12-5.22 5.03L6.96.87l-.6-.48-.12-.1-.1.1-6.1 5.7-.04.06v5.76l.05.05 11.4 10.87.12.1.12-.1 11.37-10.87.05-.05V6.17l-.05-.05z\"/></svg>') no-repeat;\n\tdisplay: none;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 30px;\n\theight: 30px;\n}\n." + WIKIA_CLASS + " .item-box:hover > .wikia-link\n{\n\tdisplay: block;\n}\n\t\t");
- function setWikiaLinksVisibility(init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var show = settings.get(settings.KEY.wikiaLinks);
- document.body.classList[show ? 'add' : 'remove'](WIKIA_CLASS);
- if (init)
- {
- settings.observe(settings.KEY.wikiaLinks, function ()
- {
- return setWikiaLinksVisibility();
- });
- }
- }
- setWikiaLinksVisibility(true);
- var boxes = document.getElementsByClassName('item-box');
- function disableClickPropagation(el)
- {
- el.addEventListener('click', function (event)
- {
- event.stopPropagation();
- });
- }
- for (var i = 0; i < boxes.length; i++)
- {
- var box = boxes.item(i);
- var key = box.id.replace(/^item-box-/, '');
- var linkArea = document.createElement('a');
- linkArea.className = 'wikia-link';
- linkArea.href = getWikiaLink(key);
- linkArea.target = '_blank';
- disableClickPropagation(linkArea);
- box.appendChild(linkArea);
- var tooltipEl = ensureTooltip('wikiLink', linkArea);
- if (tooltipEl.innerHTML === '')
- {
- tooltipEl.innerHTML = "Click to open the wikia page about this item.";
- }
- }
- }
- function init()
- {
- addFurnaceCaption();
- addOilStorageCaption();
- addOilCaption();
- addWandCaption();
- addVariousCaptions();
- addTierCaption();
- addBoatCaption();
- addBonemealCaption();
- warningBeforeSellingGems();
- addWikiaLinks();
- }
- itemBoxes.init = init;
- })(itemBoxes || (itemBoxes = {}));
- /**
- * add new chat
- */
- var chat;
- (function (chat)
- {
- chat.name = 'chat';
- // min time difference between repeated messages to not be considered as spam
- var MIN_DIFF_REPEATED_MSG = 5e3;
- var KEYWORD_LIST_KEY = 'keywordList';
- var keywordList = store.get(KEYWORD_LIST_KEY) || [];
- var CHAT_HISTORY_KEY = 'chatHistory';
- var MAX_CHAT_HISTORY_LENGTH = 100;
- var Type;
- (function (Type)
- {
- Type[Type["reload"] = -1] = "reload";
- Type[Type["normal"] = 0] = "normal";
- Type[Type["pmReceived"] = 1] = "pmReceived";
- Type[Type["pmSent"] = 2] = "pmSent";
- Type[Type["serverMsg"] = 3] = "serverMsg";
- })(Type || (Type = {}));;
- var Tag;
- (function (Tag)
- {
- Tag[Tag["none"] = 0] = "none";
- Tag[Tag["donor"] = 1] = "donor";
- Tag[Tag["contributor"] = 2] = "contributor";
- Tag[Tag["mod"] = 3] = "mod";
- Tag[Tag["dev"] = 4] = "dev";
- Tag[Tag["server"] = 5] = "server";
- })(Tag || (Tag = {}));;
- /**
- * The chunk hiding starts with at least 10 chunks.
- * So there are at least
- * (chunkHidingMinChunks-1) * msgChunkSize + 1 = 9 * 100 + 1 = 901
- * messages before the chunk hiding mechanism starts.
- */
- var CHUNK_HIDING_MIN_CHUNKS = 10;
- var MSG_CHUNK_SIZE = 100;
- var RELOADED_CHAT_DATA = {
- timestamp: 0
- , username: ''
- , userlevel: 0
- , icon: 0
- , tag: 0
- , type: Type.reload
- , msg: '[...]'
- };
- var CHAT_BOX_ID = 'div-chat';
- var DEFAULT_CHAT_DIV_ID = 'div-chat-area';
- var GENERAL_CHAT_DIV_ID = 'div-chat-general';
- var PM_CHAT_TAB_PREFIX = 'tab-chat-pm-';
- var PM_CHAT_DIV_PREFIX = 'div-chat-pm-';
- var CHAT_TABS_ID = 'chat-tabs';
- var CHAT_INPUT_ID = 'chat-input-text';
- var CHAT_CLASS = 'div-chat-area';
- var COLORIZE_CLASS = 'colorize';
- var SpecialTab;
- (function (SpecialTab)
- {
- SpecialTab[SpecialTab["default"] = 0] = "default";
- SpecialTab[SpecialTab["general"] = 1] = "general";
- SpecialTab[SpecialTab["filler"] = 2] = "filler";
- })(SpecialTab || (SpecialTab = {}));;
- var CHAT_SPECIAL_TAB_ID = (_a = {}
- , _a[SpecialTab.default] = 'tab-chat-default'
- , _a[SpecialTab.general] = 'tab-chat-general'
- , _a[SpecialTab.filler] = 'tab-chat-filler'
- , _a);
- var CONTEXTMENU_ID = 'player-contextmenu';
- var CHAT_ICONS = [
- null
- , {
- key: 'halloween2015'
- , title: 'Halloween 2015'
- }
- , {
- key: 'christmas2015'
- , title: 'Chirstmas 2015'
- }
- , {
- key: 'easter2016'
- , title: 'Holiday'
- }
- , {
- key: 'halloween2016'
- , title: 'Halloween 2016'
- }
- , {
- key: 'christmas2016'
- , title: 'Chirstmas 2016'
- }
- , {
- key: 'dh1Max'
- , title: 'Max Level in DH1'
- }
- , {
- key: 'hardcore'
- , title: 'Hardcore Account'
- }
- , {
- key: 'quest'
- , title: 'Questmaster'
- }
- ];
- var CHAT_TAGS = [
- null
- , {
- key: 'donor'
- , name: ''
- }
- , {
- key: 'contributor'
- , name: 'Contributor'
- }
- , {
- key: 'mod'
- , name: 'Moderator'
- }
- , {
- key: 'dev'
- , name: 'Dev'
- }
- , {
- key: 'yell'
- , name: 'Server Message'
- }
- ];
- var LOCALE = 'en-US';
- var LOCALE_OPTIONS = {
- hour12: false
- , year: 'numeric'
- , month: 'long'
- , day: 'numeric'
- , hour: '2-digit'
- , minute: '2-digit'
- , second: '2-digit'
- };
- // game commands
- var COMMANDS = [
- 'pm'
- , 'mute'
- , 'clear'
- , 'ipmute'
- ];
- var CLEAR_CMD = 'clear';
- var TUTORIAL_CMD = 'tutorial';
- var KEYWORD_ADD_CMD = 'keyword add';
- var KEYWORD_REMOVE_CMD = 'keyword remove';
- // load chat history
- var chatHistory = store.get(CHAT_HISTORY_KEY) || [];
- // store chat colors for each user
- var user2Color;
- var usedColors;
- // reserve color for special messages (e.g. server messages): white
- var reservedColors = ['#ffffff'];
- // message chunks
- var msgChunkMap = new Map();
- // for adding elements at startup
- var chatboxFragments = new Map();
- var chatInitialized = false;
- // find index of last message which is not a pm
- var isLastMsgNotReload = false;
- for (var i = chatHistory.length - 1; i >= 0; i--)
- {
- if (!isDataPM(chatHistory[i]))
- {
- isLastMsgNotReload = chatHistory[i].type != Type.reload;
- break;
- }
- }
- // insert a placeholder for a reloaded chat
- if (isLastMsgNotReload)
- {
- RELOADED_CHAT_DATA.timestamp = (new Date()).getTime();
- chatHistory.push(RELOADED_CHAT_DATA);
- }
- function isMuted(user)
- {
- // ATTENTION: this will filter all people who are named similar to one of the muted people!
- return window.mutedPeople.some(function (name)
- {
- return user.indexOf(name) > -1;
- });
- // return window.mutedPeople.indexOf(user) !== -1;
- }
- function isSpam(data)
- {
- // allow all messages from contributors, mods, devs and all server messages
- if (data.tag != Tag.none)
- {
- return false;
- }
- /**
- * get last message of current user
- */
- var isThisPm = isDataPM(data);
- var msgUsername = data.type === Type.pmSent ? window.username : data.username;
- var historyIndex = chatHistory.indexOf(data);
- if (historyIndex == -1)
- {
- historyIndex = chatHistory.length;
- }
- var lastData = null;
- for (var i = historyIndex - 1; i >= 0 && (lastData === null); i--)
- {
- var dataBefore = chatHistory[i];
- if (isThisPm === isDataPM(dataBefore))
- {
- var beforeUsername = dataBefore.type == Type.pmSent ? window.username : dataBefore.username;
- if (beforeUsername === msgUsername)
- {
- lastData = dataBefore;
- }
- }
- }
- /**
- * compare message and don't allow the same message twice
- */
- if (lastData
- && lastData.msg === data.msg
- && (data.timestamp - lastData.timestamp) < MIN_DIFF_REPEATED_MSG)
- {
- return true;
- }
- return false;
- }
- function handleScrolling(chatbox)
- {
- if (window.isAutoScrolling)
- {
- setTimeout(function ()
- {
- return chatbox.scrollTop = chatbox.scrollHeight;
- });
- }
- }
- // for chat messages which arrive before DOMContentLoaded and can not be displayed since the DOM isn't ready
- function processChatData(username, iconString, tagString, msg, isPM)
- {
- var tag = parseInt(tagString, 10);
- var userlevel = 0;
- var type = Type.normal;
- if (isPM == 1)
- {
- var match = msg.match(/^\s*\[(PM from|Sent to) ([A-Za-z0-9 ]+)\]: (.+?)\s*$/) || ['', '', username, msg];
- type = match[1] == 'Sent to' ? Type.pmSent : Type.pmReceived;
- username = match[2].replace(/_/g, ' ');
- msg = match[3];
- }
- else if (tag == Tag.server)
- {
- type = Type.serverMsg;
- }
- else
- {
- var match = msg.match(/^\s*\((\d+)\): (.+?)\s*$/);
- if (match)
- {
- userlevel = parseInt(match[1], 10);
- msg = match[2];
- }
- else
- {
- userlevel = window.getGlobalLevel();
- }
- }
- // unlinkify when using DH2QoL to store the plain message
- if (window.addToChatBox.toString().includes('linkify(arguments[3])'))
- {
- msg = msg.replace(/<a href='([^']+)' target='_blank'>\1<\/a>/ig, '$1');
- }
- if (type == Type.pmSent)
- {
- // turn some critical characters into HTML entities
- msg = msg.replace(/[<>]/g, function (char)
- {
- return '&#' + char.charCodeAt(0) + ';';
- });
- }
- return {
- timestamp: now()
- , username: username
- , userlevel: userlevel
- , icon: parseInt(iconString, 10)
- , tag: tag
- , type: type
- , msg: msg
- };
- }
- function saveChatHistory()
- {
- store.set(CHAT_HISTORY_KEY, chatHistory);
- }
- function add2ChatHistory(data)
- {
- chatHistory.push(data);
- chatHistory = chatHistory.slice(-MAX_CHAT_HISTORY_LENGTH);
- saveChatHistory();
- }
- function username2Id(username)
- {
- return username.replace(/ /g, '_');
- }
- function getChatTab(username, specialTab)
- {
- var id = (specialTab != null)
- ? CHAT_SPECIAL_TAB_ID[specialTab]
- : PM_CHAT_TAB_PREFIX + username2Id(username);
- var tab = document.getElementById(id);
- if (!tab)
- {
- tab = document.createElement('div');
- tab.className = 'chat-tab';
- if (specialTab != null)
- {
- tab.classList.add(SpecialTab[specialTab]);
- }
- tab.id = id;
- tab.dataset.username = username;
- tab.dataset.new = '0';
- if (username.length > 2)
- {
- tab.textContent = username;
- // thanks /u/Spino-Prime for pointing out this was missing
- var closeSpan = document.createElement('span');
- closeSpan.className = 'close';
- tab.appendChild(closeSpan);
- }
- var chatTabs = document.getElementById(CHAT_TABS_ID);
- var filler = chatTabs.querySelector('.filler');
- if (filler)
- {
- chatTabs.insertBefore(tab, filler);
- }
- else
- {
- chatTabs.appendChild(tab);
- }
- }
- return tab;
- }
- function getChatPanel(username)
- {
- var id = username == '' ? GENERAL_CHAT_DIV_ID : PM_CHAT_DIV_PREFIX + username2Id(username);
- var panel = document.getElementById(id);
- if (!panel)
- {
- panel = document.createElement('div');
- panel.setAttribute('disabled', 'disabled');
- panel.id = id;
- panel.className = CHAT_CLASS;
- var defaultChat = document.getElementById(DEFAULT_CHAT_DIV_ID);
- var height = defaultChat.style.height;
- panel.style.height = height;
- var chatDiv = defaultChat.parentElement;
- chatDiv.insertBefore(panel, defaultChat);
- }
- return panel;
- }
- function changeChatTab(oldTab, newTab)
- {
- if (oldTab)
- {
- oldTab.classList.remove('selected');
- var oldChatPanel = void 0;
- if (oldTab.classList.contains('default'))
- {
- oldChatPanel = document.getElementById(DEFAULT_CHAT_DIV_ID);
- }
- else
- {
- oldChatPanel = getChatPanel(oldTab.dataset.username || '');
- }
- oldChatPanel.classList.remove('selected');
- }
- newTab.classList.add('selected');
- newTab.dataset.new = '0';
- var newChatPanel;
- if (newTab.classList.contains('default'))
- {
- newChatPanel = document.getElementById(DEFAULT_CHAT_DIV_ID);
- }
- else
- {
- newChatPanel = getChatPanel(newTab.dataset.username || '');
- }
- newChatPanel.classList.add('selected');
- var toUsername = newTab.dataset.username;
- var newTextPlaceholder = toUsername == '' ? window.username + ':' : 'PM to ' + toUsername + ':';
- document.getElementById(CHAT_INPUT_ID).placeholder = newTextPlaceholder;
- if (window.isAutoScrolling)
- {
- setTimeout(function ()
- {
- return newChatPanel.scrollTop = newChatPanel.scrollHeight;
- });
- }
- }
- function clearChat(username)
- {
- // delete pms stored for that user
- var isPMChat = username != '';
- for (var i = 0; i < chatHistory.length; i++)
- {
- var data = chatHistory[i];
- if (isPMChat == isDataPM(data) && (!isPMChat || data.username == username))
- {
- chatHistory.splice(i, 1);
- i--;
- }
- }
- saveChatHistory();
- // clear pm-chat panel
- var panel = getChatPanel(username);
- while (panel.children.length > 0)
- {
- panel.removeChild(panel.children[0]);
- }
- msgChunkMap.delete(username);
- return panel;
- }
- function closeChatTab(username)
- {
- // clear pm-chat panel and remove message-history
- clearChat(username);
- // remove pm-tab (and change tab if necessary)
- var selectedTab = getSelectedTab();
- var tab2Close = getChatTab(username, null);
- if (selectedTab.dataset.username == username)
- {
- var generalTab = getChatTab('', SpecialTab.general);
- changeChatTab(tab2Close, generalTab);
- }
- var tabContainer = tab2Close.parentElement;
- tabContainer.removeChild(tab2Close);
- }
- function isDataPM(data)
- {
- return data.type === Type.pmSent || data.type === Type.pmReceived;
- }
- function colorizeMsg(username)
- {
- if (username == '')
- {
- return null;
- }
- if (!user2Color.has(username))
- {
- var color = void 0;
- do {
- var colorizer = settings.getSub(settings.KEY.colorizeChat, 'colorizer');
- if (colorizer == 1)
- {
- color = colorGenerator.getRandom(
- {
- luminosity: 'light'
- });
- }
- else if (colorizer == 2)
- {
- color = colorGenerator.getRandom(
- {
- luminosity: 'dark'
- });
- }
- else
- {
- color = colorGenerator.getEquallyDistributed();
- }
- } while (usedColors.has(color));
- user2Color.set(username, color);
- usedColors.add(color);
- addStyle("\n#" + CHAT_BOX_ID + "." + COLORIZE_CLASS + " .chat-msg[data-username=\"" + username + "\"]\n{\n\tbackground-color: " + color + ";\n}\n\t\t\t", 'name-color');
- }
- return user2Color.get(username);
- }
- function createMessageSegment(data)
- {
- var isThisPm = isDataPM(data);
- var msgUsername = data.type === Type.pmSent ? window.username : data.username;
- var historyIndex = chatHistory.indexOf(data);
- var isSameUser = null;
- var isSameTime = null;
- for (var i = historyIndex - 1; i >= 0 && (isSameUser === null || isSameTime === null); i--)
- {
- var dataBefore = chatHistory[i];
- if (isThisPm === isDataPM(dataBefore))
- {
- if (isSameUser === null)
- {
- var beforeUsername = dataBefore.type == Type.pmSent ? window.username : dataBefore.username;
- isSameUser = beforeUsername === msgUsername;
- }
- if (dataBefore.type != Type.reload)
- {
- isSameTime = Math.floor(data.timestamp / 1000 / 60) - Math.floor(dataBefore.timestamp / 1000 / 60) === 0;
- }
- }
- }
- var d = new Date(data.timestamp);
- var hour = (d.getHours() < 10 ? '0' : '') + d.getHours();
- var minute = (d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
- var icon = CHAT_ICONS[data.icon] ||
- {
- key: ''
- , title: ''
- };
- var tag = CHAT_TAGS[data.tag] ||
- {
- key: ''
- , name: ''
- };
- var formattedMsg = data.msg
- .replace(/<a href='(.+?)' target='_blank'>\1<\/a>/g, '$1')
- .replace(/(https?:\/\/[^\s"<>]+)/g, '<a target="_blank" href="$1">$1</a>');
- colorizeMsg(msgUsername);
- var msgTitle = data.type == Type.reload ? 'Chat loaded on ' + d.toLocaleString(LOCALE, LOCALE_OPTIONS) : '';
- var user = data.type === Type.serverMsg ? 'Server Message' : msgUsername;
- var levelAppendix = data.type == Type.normal ? ' (' + data.userlevel + ')' : '';
- var userTitle = data.tag != Tag.server ? tag.name : '';
- return "<span class=\"chat-msg\" data-type=\"" + data.type + "\" data-tag=\"" + tag.key + "\" data-username=\"" + msgUsername + "\">"
- + ("<span\n\t\t\t\tclass=\"timestamp\"\n\t\t\t\tdata-timestamp=\"" + data.timestamp + "\"\n\t\t\t\tdata-same-time=\"" + isSameTime + "\">" + hour + ":" + minute + "</span>")
- + ("<span class=\"user\" data-name=\"" + msgUsername + "\" data-same-user=\"" + isSameUser + "\">")
- + ("<span class=\"icon " + icon.key + "\" title=\"" + icon.title + "\"></span>")
- + ("<span class=\"name chat-tag-" + tag.key + "\" title=\"" + userTitle + "\">" + user + levelAppendix + ":</span>")
- + "</span>"
- + ("<span class=\"msg\" title=\"" + msgTitle + "\">" + formattedMsg + "</span>")
- + "</span>";
- }
- function add2Chat(data)
- {
- if (!chatInitialized)
- {
- return;
- }
- var isThisPm = isDataPM(data);
- // don't mute pms (you can just ignore pm-tab if you like)
- if (!isThisPm && isMuted(data.username))
- {
- return;
- }
- var userKey = isThisPm ? data.username : '';
- var chatTab = getChatTab(userKey, isThisPm ? null : SpecialTab.general);
- if (!chatTab.classList.contains('selected'))
- {
- chatTab.dataset.new = (parseInt(chatTab.dataset.new || '0', 10) + 1).toString();
- }
- if (isThisPm)
- {
- window.lastPMUser = data.username;
- }
- // username is 3-12 characters long
- var chatbox = getChatPanel(userKey);
- var msgChunk = msgChunkMap.get(userKey);
- if (!msgChunk || msgChunk.children.length >= MSG_CHUNK_SIZE)
- {
- msgChunk = document.createElement('div');
- msgChunk.className = 'msg-chunk';
- msgChunkMap.set(userKey, msgChunk);
- if (chatboxFragments != null)
- {
- if (!chatboxFragments.has(userKey))
- {
- chatboxFragments.set(userKey, document.createDocumentFragment());
- }
- chatboxFragments.get(userKey).appendChild(msgChunk);
- }
- else
- {
- chatbox.appendChild(msgChunk);
- }
- }
- var tmp = document.createElement('templateWrapper');
- tmp.innerHTML = createMessageSegment(data);
- msgChunk.appendChild(tmp.children[0]);
- handleScrolling(chatbox);
- }
- function applyChatStyle()
- {
- addStyle("\nspan.chat-msg\n{\n\tdisplay: flex;\n\tmin-height: 21px;\n\tpadding: 1px 0;\n}\n#" + CHAT_BOX_ID + ":not(." + COLORIZE_CLASS + ") span.chat-msg:nth-child(2n)\n{\n\tbackground-color: hsla(0, 0%, 90%, 1);\n}\n.chat-msg[data-type=\"" + Type.reload + "\"]\n{\n\tfont-size: 0.8rem;\n\tline-height: 1.2rem;\n}\n.chat-msg .timestamp\n{\n\tdisplay: none;\n}\n#" + CHAT_BOX_ID + ".showTimestamps .chat-msg:not([data-type=\"" + Type.reload + "\"]) .timestamp\n{\n\tcolor: hsla(0, 0%, 50%, 1);\n\tdisplay: inline-block;\n\tfont-size: .9rem;\n\tmargin: 0;\n\tmargin-right: 5px;\n\tposition: relative;\n\twidth: 2.5rem;\n}\n.chat-msg .timestamp[data-same-time=\"true\"]\n{\n\tcolor: hsla(0, 0%, 50%, .1);\n}\n.chat-msg:not([data-type=\"" + Type.reload + "\"]) .timestamp:hover::after\n{\n\tbackground-color: hsla(0, 0%, 12%, 1);\n\tborder-radius: .2rem;\n\tcontent: attr(data-fulltime);\n\tcolor: hsla(0, 0%, 100%, 1);\n\tline-height: 1.35rem;\n\tpadding: .4rem .8rem;\n\tpointer-events: none;\n\tposition: absolute;\n\tleft: 2.5rem;\n\ttop: -0.4rem;\n\ttext-align: center;\n\twhite-space: nowrap;\n}\n\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-type=\"" + Type.pmReceived + "\"] { color: purple; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-type=\"" + Type.pmSent + "\"] { color: purple; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-type=\"" + Type.serverMsg + "\"] { color: blue; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-tag=\"contributor\"] { color: green; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-tag=\"mod\"] { color: #669999; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-tag=\"dev\"] { color: #666600; }\n.chat-msg:not([data-type=\"" + Type.reload + "\"]) .user\n{\n\tflex: 0 0 132px;\n\tmargin-right: 5px;\n\twhite-space: nowrap;\n}\n#" + GENERAL_CHAT_DIV_ID + " .chat-msg:not([data-type=\"" + Type.reload + "\"]) .user\n{\n\tflex-basis: 182px;\n}\n#" + CHAT_BOX_ID + ".showIcons #" + GENERAL_CHAT_DIV_ID + " .chat-msg:not([data-type=\"" + Type.reload + "\"]) .user\n{\n\tpadding-left: 22px;\n}\n.chat-msg .user[data-same-user=\"true\"]:not([data-name=\"\"])\n{\n\tcursor: default;\n\topacity: 0;\n}\n\n.chat-msg .user .icon\n{\n\tdisplay: none;\n}\n#" + CHAT_BOX_ID + ".showIcons .chat-msg .user .icon\n{\n\tdisplay: inline-block;\n\tmargin-left: -22px;\n}\n.chat-msg .user .icon::before\n{\n\tbackground-size: 20px 20px;\n\tcontent: '';\n\tdisplay: inline-block;\n\tmargin-right: 2px;\n\twidth: 20px;\n\theight: 20px;\n\tvertical-align: middle;\n}\n.chat-msg .user .icon.halloween2015::before\t{ background-image: url('images/chat-icons/1.png'); }\n.chat-msg .user .icon.christmas2015::before\t{ background-image: url('images/chat-icons/2.png'); }\n.chat-msg .user .icon.easter2016::before\t{ background-image: url('images/chat-icons/3.png'); }\n.chat-msg .user .icon.halloween2016::before\t{ background-image: url('images/chat-icons/4.png'); }\n.chat-msg .user .icon.christmas2016::before\t{ background-image: url('images/chat-icons/5.png'); }\n.chat-msg .user .icon.dh1Max::before\t\t{ background-image: url('images/chat-icons/6.png'); }\n.chat-msg .user .icon.hardcore::before\t\t{ background-image: url('images/chat-icons/7.png'); }\n.chat-msg .user .icon.quest::before\t\t\t{ background-image: url('images/chat-icons/8.png'); }\n\n.chat-msg .user:not([data-same-user=\"true\"]) .name\n{\n\tcolor: rgba(0, 0, 0, 0.7);\n\tcursor: pointer;\n}\n.chat-msg .user .name.chat-tag-donor::before\n{\n\tbackground-image: url('images/chat-icons/donor.png');\n\tbackground-size: 20px 20px;\n\tcontent: '';\n\tdisplay: inline-block;\n\theight: 20px;\n\twidth: 20px;\n\tvertical-align: middle;\n}\n.chat-msg .user .name.chat-tag-yell\n{\n\tcursor: default;\n}\n#" + CHAT_BOX_ID + ".showTags .chat-msg .user .name.chat-tag-contributor,\n#" + CHAT_BOX_ID + ".showTags .chat-msg .user .name.chat-tag-mod,\n#" + CHAT_BOX_ID + ".showTags .chat-msg .user .name.chat-tag-dev,\n#" + CHAT_BOX_ID + ".showTags .chat-msg .user .name.chat-tag-yell\n{\n\tcolor: white;\n\tdisplay: inline-block;\n\tfont-size: 10pt;\n\tmargin-bottom: -1px;\n\tmargin-top: -1px;\n\tpadding-bottom: 2px;\n\ttext-align: center;\n\t/* 2px border, 10 padding */\n\twidth: calc(100% - 2*1px - 2*5px);\n}\n#" + CHAT_BOX_ID + ":not(.showTags) .chat-msg .user .name.chat-tag-contributor,\n#" + CHAT_BOX_ID + ":not(.showTags) .chat-msg .user .name.chat-tag-mod,\n#" + CHAT_BOX_ID + ":not(.showTags) .chat-msg .user .name.chat-tag-dev,\n#" + CHAT_BOX_ID + ":not(.showTags) .chat-msg .user .name.chat-tag-yell\n{\n\tbackground: initial;\n\tborder: inherit;\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: initial;\n}\n\n.chat-msg[data-type=\"" + Type.reload + "\"] .user > *,\n.chat-msg[data-type=\"" + Type.pmReceived + "\"] .user > .icon,\n.chat-msg[data-type=\"" + Type.pmSent + "\"] .user > .icon\n{\n\tdisplay: none;\n}\n\n.chat-msg .msg\n{\n\tmin-width: 0;\n\toverflow: hidden;\n\tword-wrap: break-word;\n}\n\n#" + CHAT_BOX_ID + " ." + CHAT_CLASS + "\n{\n\twidth: 100%;\n\theight: 130px;\n\tdisplay: none;\n}\n#" + CHAT_BOX_ID + " ." + CHAT_CLASS + ".selected\n{\n\tdisplay: block;\n}\n#" + CHAT_TABS_ID + "\n{\n\tdisplay: flex;\n\tmargin: 10px -6px -6px;\n\tflex-wrap: wrap;\n}\n#" + CHAT_TABS_ID + " .chat-tab\n{\n\tbackground-color: gray;\n\tborder-top: 1px solid black;\n\tborder-right: 1px solid black;\n\tcursor: pointer;\n\tdisplay: inline-block;\n\tfont-weight: normal;\n\tpadding: 0.3rem .6rem;\n\tposition: relative;\n}\n#" + CHAT_TABS_ID + " .chat-tab.selected\n{\n\tbackground-color: transparent;\n\tborder-top-color: transparent;\n}\n#" + CHAT_TABS_ID + " .chat-tab.default\n{\n\tdisplay: none;\n}\n#" + CHAT_TABS_ID + " .chat-tab.filler\n{\n\tbackground-color: hsla(0, 0%, 90%, 1);\n\tborder-right: 0;\n\tbox-shadow: inset 5px 5px 5px -5px rgba(0, 0, 0, 0.5);\n\tcolor: transparent;\n\tcursor: default;\n\tflex-grow: 1;\n}\n#" + CHAT_TABS_ID + " .chat-tab::after\n{\n\tcolor: white;\n\tcontent: '(' attr(data-new) ')';\n\tfont-size: .9rem;\n\tfont-weight: bold;\n\tmargin-left: .4rem;\n}\n#" + CHAT_TABS_ID + " .chat-tab[data-new=\"0\"]::after\n{\n\tcolor: inherit;\n\tfont-weight: normal;\n}\n#" + CHAT_TABS_ID + " .chat-tab:not(.general).selected::after,\n#" + CHAT_TABS_ID + " .chat-tab:not(.general):hover::after\n{\n\tvisibility: hidden;\n}\n#" + CHAT_TABS_ID + " .chat-tab:not(.general).selected .close::after,\n#" + CHAT_TABS_ID + " .chat-tab:not(.general):hover .close::after\n{\n\tcontent: '\u00D7';\n\tfont-size: 1.5rem;\n\tposition: absolute;\n\ttop: 0;\n\tright: .6rem;\n\tbottom: 0;\n}\n\n#" + CONTEXTMENU_ID + "\n{\n\tbox-shadow: rgba(0, 0, 0, 0.8) 4px 4px 4px -2px;\n\tposition: fixed;\n}\n#" + CONTEXTMENU_ID + " .ui-widget-header\n{\n\tcursor: default;\n\tpadding: .25rem;\n}\n\t\t");
- }
- function initColorizer(init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var usernameList = user2Color && Array.from(user2Color.keys()) || [];
- user2Color = new Map();
- usedColors = new Set();
- for (var _i = 0, reservedColors_1 = reservedColors; _i < reservedColors_1.length; _i++)
- {
- var color = reservedColors_1[_i];
- usedColors.add(color);
- }
- var colorStyle = getStyle('name-color');
- colorStyle.innerHTML = '';
- for (var _a = 0, usernameList_1 = usernameList; _a < usernameList_1.length; _a++)
- {
- var username = usernameList_1[_a];
- colorizeMsg(username);
- }
- if (init)
- {
- settings.observeSub(settings.KEY.colorizeChat, 'colorizer', function ()
- {
- return initColorizer();
- });
- }
- }
- function addIntelligentScrolling()
- {
- // add checkbox instead of button for toggling auto scrolling
- var btn = document.querySelector('input[value="Toggle Autoscroll"]');
- var btnParent = btn.parentElement;
- var checkboxId = 'chat-toggle-autoscroll';
- // create checkbox
- var toggleCheckbox = document.createElement('input');
- toggleCheckbox.type = 'checkbox';
- toggleCheckbox.id = checkboxId;
- toggleCheckbox.checked = true;
- // create label
- var toggleLabel = document.createElement('label');
- toggleLabel.htmlFor = checkboxId;
- toggleLabel.textContent = 'Autoscroll';
- btnParent.insertBefore(toggleCheckbox, btn);
- btnParent.insertBefore(toggleLabel, btn);
- btn.style.display = 'none';
- var chatArea = document.getElementById(GENERAL_CHAT_DIV_ID);
- var showScrollTextTimeout = null;
- function setAutoScrolling(value, full)
- {
- if (full === void 0)
- {
- full = false;
- }
- if (window.isAutoScrolling != value)
- {
- toggleCheckbox.checked = value;
- window.isAutoScrolling = value;
- var icon_1 = 'none';
- var color_1 = value ? 'lime' : 'red';
- var text_1 = (value ? 'En' : 'Dis') + 'abled' + (full ? ' Autoscroll' : '');
- if (full)
- {
- if (showScrollTextTimeout)
- {
- window.clearTimeout(showScrollTextTimeout);
- }
- showScrollTextTimeout = window.setTimeout(function ()
- {
- return window.scrollText(icon_1, color_1, text_1);
- }, 300);
- }
- else
- {
- window.scrollText(icon_1, color_1, text_1);
- }
- return true;
- }
- return false;
- }
- toggleCheckbox.addEventListener('change', function ()
- {
- setAutoScrolling(this.checked);
- if (this.checked && settings.get(settings.KEY.intelligentScrolling))
- {
- chatArea.scrollTop = chatArea.scrollHeight - chatArea.clientHeight;
- }
- });
- var placeholderTemplate = document.createElement('div');
- placeholderTemplate.className = 'placeholder';
- var childStore = new WeakMap();
- function scrollHugeChat()
- {
- // # of children
- var chunkNum = chatArea.children.length;
- // start chunk hiding at a specific amount of chunks
- if (chunkNum < CHUNK_HIDING_MIN_CHUNKS)
- {
- return;
- }
- var visibleTop = chatArea.scrollTop;
- var visibleBottom = visibleTop + chatArea.clientHeight;
- var referenceTop = visibleTop - window.innerHeight;
- var referenceBottom = visibleBottom + window.innerHeight;
- var top = 0;
- // never hide the last element since its size may change at any time when a new message gets appended
- for (var i = 0; i < chunkNum - 1; i++)
- {
- var child = chatArea.children[i];
- var height = child.clientHeight;
- var bottom = top + height;
- var isVisible = top >= referenceTop && top <= referenceBottom
- || bottom >= referenceTop && bottom <= referenceBottom
- || top < referenceTop && bottom > referenceBottom;
- var isPlaceholder = child.classList.contains('placeholder');
- if (!isVisible && !isPlaceholder)
- {
- var newPlaceholder = placeholderTemplate.cloneNode(false);
- newPlaceholder.style.height = height + 'px';
- chatArea.replaceChild(newPlaceholder, child);
- childStore.set(newPlaceholder, child);
- }
- else if (isVisible && isPlaceholder)
- {
- var oldChild = childStore.get(child);
- chatArea.replaceChild(oldChild, child);
- childStore.delete(child);
- }
- top = bottom;
- }
- }
- var delayedScrollStart = null;
- var delayedScrollTimeout = null;
- // does not consider pm tabs; may be changed in a future version?
- chatArea.addEventListener('scroll', function ()
- {
- if (settings.get(settings.KEY.intelligentScrolling))
- {
- var scrolled2Bottom = (chatArea.scrollTop + chatArea.clientHeight) >= chatArea.scrollHeight;
- setAutoScrolling(scrolled2Bottom, true);
- }
- var n = now();
- if (delayedScrollStart == null)
- {
- delayedScrollStart = n;
- }
- if (delayedScrollStart + 300 > n)
- {
- if (delayedScrollTimeout)
- {
- window.clearTimeout(delayedScrollTimeout);
- }
- delayedScrollTimeout = window.setTimeout(function ()
- {
- delayedScrollStart = null;
- delayedScrollTimeout = null;
- scrollHugeChat();
- }, 50);
- }
- });
- }
- function getSelectedTab()
- {
- return document.querySelector('#' + CHAT_TABS_ID + ' .chat-tab.selected');
- }
- function getSelectedTabUsername()
- {
- var selectedTab = getSelectedTab();
- return selectedTab.dataset.username || '';
- }
- function clickChatTab(newTab)
- {
- var oldTab = getSelectedTab();
- if (newTab == oldTab)
- {
- return;
- }
- changeChatTab(oldTab, newTab);
- }
- function clickCloseChatTab(tab)
- {
- var username = tab.dataset.username || '';
- var chatPanel = getChatPanel(username);
- if (chatPanel.children.length === 0
- || confirm("Do you want to close the pm tab of \"" + username + "\"?"))
- {
- closeChatTab(username);
- }
- }
- function checkSetting(init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var enabled = settings.get(settings.KEY.useNewChat);
- // dis-/enable chat tabs
- var chatTabs = document.getElementById(CHAT_TABS_ID);
- chatTabs.style.display = enabled ? '' : 'none';
- // dis-/enable checkbox for intelligent scrolling
- var intelScrollId = 'chat-toggle-intelligent-scroll';
- var input = document.getElementById(intelScrollId);
- if (input)
- {
- input.style.display = enabled ? '' : 'none';
- }
- var label = document.querySelector('label[for="' + intelScrollId + '"]');
- if (label)
- {
- label.style.display = enabled ? '' : 'none';
- }
- // virtually click on a tab
- var defaultTab = getChatTab('', SpecialTab.default);
- var generalTab = getChatTab('', SpecialTab.general);
- clickChatTab(enabled ? generalTab : defaultTab);
- if (init)
- {
- settings.observe(settings.KEY.useNewChat, function ()
- {
- return checkSetting(false);
- });
- }
- }
- function addChatTabs()
- {
- var chatBoxArea = document.getElementById(CHAT_BOX_ID);
- var chatTabs = document.createElement('div');
- chatTabs.id = CHAT_TABS_ID;
- chatTabs.addEventListener('click', function (event)
- {
- var newTab = event.target;
- if (newTab.classList.contains('close'))
- {
- return clickCloseChatTab(newTab.parentElement);
- }
- if (!newTab.classList.contains('chat-tab') || newTab.classList.contains('filler'))
- {
- return;
- }
- clickChatTab(newTab);
- });
- chatBoxArea.appendChild(chatTabs);
- // default tab (for disabled new chat)
- getChatTab('', SpecialTab.default);
- // general server chat
- var generalTab = getChatTab('', SpecialTab.general);
- generalTab.textContent = 'Server';
- getChatPanel('');
- getChatTab('', SpecialTab.filler);
- var _sendChat = window.sendChat;
- window.sendChat = function (inputEl)
- {
- var msg = inputEl.value;
- var selectedTab = document.querySelector('.chat-tab.selected');
- if (selectedTab.dataset.username != '' && msg[0] != '/')
- {
- inputEl.value = '/pm ' + (selectedTab.dataset.username || '').replace(/ /g, '_') + ' ' + msg;
- }
- _sendChat(inputEl);
- };
- }
- function switch2PmTab(username)
- {
- var newTab = getChatTab(username, null);
- clickChatTab(newTab);
- }
- function notifyPm(data)
- {
- notifications.event('Message from "' + data.username + '"'
- , {
- body: data.msg
- , onclick: function ()
- {
- return switch2PmTab(data.username);
- }
- , whenActive: getSelectedTab().dataset.username != data.username
- });
- }
- function checkMentionAndKeywords(data)
- {
- var lowerMsg = data.msg.toLowerCase();
- var usernameRegex = new RegExp('\\b' + window.username + '\\b', 'i');
- if (settings.getSub(settings.KEY.showNotifications, 'mention') && usernameRegex.test(lowerMsg))
- // if (lowerMsg.indexOf(window.username) > -1)
- {
- notifications.event('You\'ve been mentioned'
- , {
- body: data.msg
- });
- }
- var match = [];
- for (var _i = 0, keywordList_1 = keywordList; _i < keywordList_1.length; _i++)
- {
- var keyword = keywordList_1[_i];
- var regex = new RegExp('\\b' + keyword + '\\b', 'i');
- if (regex.test(lowerMsg))
- // if (lowerMsg.indexOf(keyword) > -1)
- {
- match.push(keyword);
- }
- }
- if (settings.getSub(settings.KEY.showNotifications, 'keyword') && match.length > 0)
- {
- notifications.event('Keyword: "' + match.join('", "') + '"'
- , {
- body: data.msg
- });
- }
- }
- var addToChatBox_ = null;
- function newAddToChatBox(username, icon, tag, msg, isPM)
- {
- var data = processChatData(username, icon, tag, msg, isPM);
- var isThisSpam = false;
- if (isDataPM(data))
- {
- if (data.type == Type.pmSent)
- {
- switch2PmTab(data.username);
- }
- notifyPm(data);
- }
- else
- {
- isThisSpam = settings.get(settings.KEY.enableSpamDetection) && isSpam(data);
- if (!isThisSpam)
- {
- // check mentioning and keywords only for non-pms
- checkMentionAndKeywords(data);
- }
- }
- if (isThisSpam)
- {
- console.info('detected spam:', data);
- }
- else
- {
- add2ChatHistory(data);
- add2Chat(data);
- }
- var fn = addToChatBox_ == null ? window.addToChatBox : addToChatBox_;
- fn(username, icon, tag, msg, isPM);
- }
- chat.newAddToChatBox = newAddToChatBox;
- function openPmTab(username)
- {
- if (username == window.username || username == '')
- {
- return;
- }
- var userTab = getChatTab(username, null);
- clickChatTab(userTab);
- var input = document.getElementById(CHAT_INPUT_ID);
- input.focus();
- }
- function newChat()
- {
- addChatTabs();
- applyChatStyle();
- initColorizer(true);
- addToChatBox_ = window.addToChatBox;
- window.addToChatBox = newAddToChatBox;
- chatInitialized = true;
- var chatbox = document.getElementById(CHAT_BOX_ID);
- chatbox.addEventListener('click', function (event)
- {
- var target = event.target;
- var userEl = target && target.parentElement;
- if (!target || !userEl || !target.classList.contains('name') || !userEl.classList.contains('user'))
- {
- return;
- }
- if (userEl.dataset.sameUser != 'true')
- {
- openPmTab(userEl.dataset.name || '');
- }
- });
- chatbox.addEventListener('mouseover', function (event)
- {
- var target = event.target;
- if (!target.classList.contains('timestamp') || !target.dataset.timestamp)
- {
- return;
- }
- var timestamp = parseInt(target.dataset.timestamp || '0', 10);
- target.dataset.fulltime = (new Date(timestamp)).toLocaleDateString(LOCALE, LOCALE_OPTIONS);
- target.dataset.timestamp = '';
- });
- // add context menu
- var contextmenu = document.createElement('ul');
- contextmenu.id = CONTEXTMENU_ID;
- contextmenu.style.display = 'none';
- contextmenu.innerHTML = "<li class=\"name ui-widget-header\"><div></div></li>\n\t\t<li class=\"open-pm\"><div>Open pm tab</div></li>\n\t\t<li class=\"stats\"><div>Open stats</div></li>\n\t\t<li class=\"mute\"><div>Mute</div></li>\n\t\t<li class=\"unmute\"><div>Unmute</div></li>";
- document.body.appendChild(contextmenu);
- window.$(contextmenu).menu(
- {
- items: '> :not(.ui-widget-header)'
- });
- var nameListEl = contextmenu.querySelector('.name');
- var nameDivEl = nameListEl.firstElementChild;
- var muteEl = contextmenu.querySelector('.mute');
- var unmuteEl = contextmenu.querySelector('.unmute');
- chatbox.addEventListener('contextmenu', function (event)
- {
- var target = event.target;
- var userEl = target && target.parentElement;
- if (!userEl || !userEl.classList.contains('user'))
- {
- return;
- }
- var username = userEl.dataset.name;
- // ignore clicks on server messages or other special messages
- if (!username || userEl.dataset.sameUser == 'true')
- {
- return;
- }
- contextmenu.style.left = event.clientX + 'px';
- contextmenu.style.top = event.clientY + 'px';
- contextmenu.style.display = '';
- contextmenu.dataset.username = username;
- nameDivEl.textContent = username;
- var isMuted = window.mutedPeople.indexOf(username) !== -1;
- muteEl.style.display = isMuted ? 'none' : '';
- unmuteEl.style.display = isMuted ? '' : 'none';
- event.stopPropagation();
- event.preventDefault();
- });
- // add click listener for context menu and stop propagation
- contextmenu.addEventListener('click', function (event)
- {
- var target = event.target;
- event.stopPropagation();
- while (target && target.id != CONTEXTMENU_ID && target.tagName != 'LI')
- {
- target = target.parentElement;
- }
- if (!target || target.id == CONTEXTMENU_ID)
- {
- return;
- }
- var username = contextmenu.dataset.username || '';
- if (target.classList.contains('open-pm'))
- {
- openPmTab(username);
- }
- else if (target.classList.contains('stats'))
- {
- window.lookup(username);
- }
- else if (target.classList.contains('mute'))
- {
- if (username == '')
- {
- return;
- }
- window.mutedPeople.push(username);
- window.scrollText('none', 'lime', '<em>' + username + '</em> muted');
- }
- else if (target.classList.contains('unmute'))
- {
- if (username == '')
- {
- return;
- }
- var index = window.mutedPeople.indexOf(username);
- if (index !== -1)
- {
- window.mutedPeople.splice(index, 1);
- }
- window.scrollText('none', 'red', '<em>' + username + '</em> unmuted');
- }
- else
- {
- return;
- }
- contextmenu.style.display = 'none';
- });
- // add click listener to hide context menu
- document.addEventListener('click', function (event)
- {
- if (contextmenu.style.display != 'none')
- {
- contextmenu.style.display = 'none';
- }
- });
- window.addEventListener('contextmenu', function (event)
- {
- if (contextmenu.style.display != 'none')
- {
- contextmenu.style.display = 'none';
- }
- });
- // handle settings
- var showSettings = [settings.KEY.showTimestamps, settings.KEY.showIcons, settings.KEY.showTags];
- function setShowSetting(key)
- {
- var enabled = settings.get(key);
- chatbox.classList[enabled ? 'add' : 'remove'](settings.KEY[key]);
- }
- for (var _i = 0, showSettings_1 = showSettings; _i < showSettings_1.length; _i++)
- {
- var key = showSettings_1[_i];
- setShowSetting(key);
- settings.observe(key, function (k)
- {
- return setShowSetting(k);
- });
- }
- }
- function addCommandSuggester()
- {
- var input = document.getElementById(CHAT_INPUT_ID);
- input.addEventListener('keyup', function (event)
- {
- if (event.key == 'Backspace' || event.key == 'Delete' || event.key == 'Enter' || event.key == 'Tab'
- || input.selectionStart != input.selectionEnd
- || input.selectionStart != input.value.length
- || !input.value.startsWith('/'))
- {
- return;
- }
- var value = input.value.substr(1);
- for (var _i = 0, COMMANDS_1 = COMMANDS; _i < COMMANDS_1.length; _i++)
- {
- var cmd = COMMANDS_1[_i];
- if (cmd.startsWith(value))
- {
- input.value = '/' + cmd;
- input.selectionStart = 1 + value.length;
- input.selectionEnd = input.value.length;
- break;
- }
- }
- });
- }
- function addOwnCommands()
- {
- COMMANDS.push(TUTORIAL_CMD);
- COMMANDS.push(KEYWORD_ADD_CMD);
- COMMANDS.push(KEYWORD_REMOVE_CMD);
- function processOwnCommands(value)
- {
- if (!value.startsWith('/'))
- {
- return value;
- }
- var msgPrefix = '/';
- var msg = value.substr(1);
- if (msg.startsWith('pm'))
- {
- var split = msg.split(' ');
- msgPrefix = '/' + split.slice(0, 2).join(' ') + ' ';
- msg = split.slice(2).join(' ');
- }
- if (msg.startsWith(CLEAR_CMD))
- {
- // clear current chat (pm chat, or general chat)
- var username = getSelectedTabUsername();
- clearChat(username);
- }
- else if (msg.startsWith(TUTORIAL_CMD))
- {
- // thanks aguyd (https://greasyfork.org/forum/profile/aguyd) for the idea
- var name_2 = msg.substr(TUTORIAL_CMD.length).trim();
- msgPrefix = '';
- msg = 'https://www.reddit.com/r/DiamondHunt/comments/5vrufh/diamond_hunt_2_starter_faq/';
- if (name_2.length != 0)
- {
- // maybe add '@' before the name?
- msg = name_2 + ', ' + msg;
- }
- }
- else if (msg.startsWith(KEYWORD_ADD_CMD))
- {
- var keyword = msg.substr(KEYWORD_ADD_CMD.length).trim().toLowerCase();
- if (keywordList.indexOf(keyword) == -1)
- {
- keywordList.push(keyword);
- store.set(KEYWORD_LIST_KEY, keywordList);
- }
- window.scrollText('none', 'lime', 'Keyword added: <em>' + keyword + '</em>');
- }
- else if (msg.startsWith(KEYWORD_REMOVE_CMD))
- {
- var keyword = msg.substr(KEYWORD_REMOVE_CMD.length).trim().toLowerCase();
- var index = keywordList.indexOf(keyword);
- if (index != -1)
- {
- keywordList.splice(index, 1);
- store.set(KEYWORD_LIST_KEY, keywordList);
- }
- window.scrollText('none', 'lime', 'Keyword removed: <em>' + keyword + '</em>');
- }
- return msgPrefix + msg;
- }
- var _sendChat = window.sendChat;
- window.sendChat = function (inputEl)
- {
- inputEl.value = processOwnCommands(inputEl.value);
- _sendChat(inputEl);
- };
- }
- function checkColorize(init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var chatDiv = document.getElementById(CHAT_BOX_ID);
- chatDiv.classList[settings.get(settings.KEY.colorizeChat) ? 'add' : 'remove'](COLORIZE_CLASS);
- if (init)
- {
- settings.observe(settings.KEY.colorizeChat, function ()
- {
- return checkColorize(false);
- });
- }
- }
- function init()
- {
- newChat();
- addIntelligentScrolling();
- addCommandSuggester();
- addOwnCommands();
- checkColorize(true);
- checkSetting(true);
- var _enlargeChat = window.enlargeChat;
- var chatBoxArea = document.getElementById(CHAT_BOX_ID);
- function setChatBoxHeight(height)
- {
- var defaultChat = document.getElementById(DEFAULT_CHAT_DIV_ID);
- defaultChat.style.height = height;
- var generalChat = document.getElementById(GENERAL_CHAT_DIV_ID);
- generalChat.style.height = height;
- var chatDivs = chatBoxArea.querySelectorAll('div[id^="' + PM_CHAT_DIV_PREFIX + '"]');
- for (var i = 0; i < chatDivs.length; i++)
- {
- chatDivs[i].style.height = height;
- }
- }
- window.enlargeChat = function (enlargeB)
- {
- _enlargeChat(enlargeB);
- var defaultChatDiv = document.getElementById(DEFAULT_CHAT_DIV_ID);
- var height = defaultChatDiv.style.height;
- store.set('chat.height', height);
- setChatBoxHeight(height);
- handleScrolling(defaultChatDiv);
- };
- setChatBoxHeight(store.get('chat.height'));
- // TEMP >>> (due to a naming issue, migrate the data)
- var oldChatHistoryKey = 'chatHistory2';
- var oldChatHistory = store.get(oldChatHistoryKey);
- if (oldChatHistory != null)
- {
- store.set(CHAT_HISTORY_KEY, oldChatHistory);
- store.remove(oldChatHistoryKey);
- }
- // TEMP <<<
- // add history to chat
- chatHistory.forEach(function (d)
- {
- return add2Chat(d);
- });
- if (chatboxFragments)
- {
- chatboxFragments.forEach(function (fragment, key)
- {
- var chatbox = getChatPanel(key);
- chatbox.appendChild(fragment);
- });
- chatboxFragments = null;
- }
- // reset the new counter for all tabs
- var tabs = document.querySelectorAll('.chat-tab');
- for (var i = 0; i < tabs.length; i++)
- {
- tabs[i].dataset.new = '0';
- }
- }
- chat.init = init;
- var _a;
- })(chat || (chat = {}));
- /**
- * hopefully only temporary fixes
- */
- var temporaryFixes;
- (function (temporaryFixes)
- {
- temporaryFixes.name = 'temporaryFixes';
- // update spells being clickable in combat
- function setSpellsClickable()
- {
- var spellbox = document.getElementById('fight-spellboox');
- if (spellbox)
- {
- spellbox.style.pointerEvents = window.isInCombat() ? '' : 'none';
- }
- }
- // warn before unloading/reloading the tab if combat is in progress
- function combatWarnOnUnload()
- {
- if (!window.isInCombat())
- {
- window.onbeforeunload = null;
- }
- else
- {
- if (window.onbeforeunload == null)
- {
- window.onbeforeunload = function ()
- {
- return 'You are in a fight!';
- };
- }
- }
- }
- function fixCombatCountdown()
- {
- var el = document.getElementById('combat-countdown');
- if (!el)
- {
- return;
- }
- if (window.isInCombat())
- {
- el.style.display = '';
- var visible = window.combatCommenceTimer != 0;
- el.style.visibility = visible ? '' : 'hidden';
- }
- }
- // fix exhaustion timer and updating brewing and cooking recipes
- function fixExhaustionTimer()
- {
- if (document.getElementById('tab-container-combat').style.display != 'none')
- {
- window.combatNotFightingTick();
- }
- }
- function fixClientGameLoop()
- {
- var _clientGameLoop = window.clientGameLoop;
- window.clientGameLoop = function ()
- {
- _clientGameLoop();
- setSpellsClickable();
- combatWarnOnUnload();
- fixCombatCountdown();
- fixExhaustionTimer();
- };
- }
- // fix elements of scrollText (e.g. when joining the game and receiving xp at that moment)
- function fixScroller()
- {
- var textEls = document.querySelectorAll('div.scroller');
- for (var i = 0; i < textEls.length; i++)
- {
- var scroller = textEls[i];
- if (scroller.style.position != 'absolute')
- {
- scroller.style.display = 'none';
- }
- }
- }
- // fix style of tooltips
- function fixTooltipStyle()
- {
- addStyle("\nbody > div.tooltip > h2:first-child\n{\n\tmargin-top: 0;\n\tfont-size: 20pt;\n\tfont-weight: normal;\n}\n\t\t");
- }
- // fix buiulding magic table dynamically
- function fixRefreshingMagicRecipes()
- {
- window.refreshLoadMagicTable = true;
- var _processMagicTab = window.processMagicTab;
- window.processMagicTab = function ()
- {
- var _refreshLoadCraftingTable = window.refreshLoadCraftingTable;
- window.refreshLoadCraftingTable = window.refreshLoadMagicTable;
- _processMagicTab();
- window.refreshLoadCraftingTable = _refreshLoadCraftingTable;
- };
- }
- // move the strange leaf to brewing tab (thanks lasse_brus for this idea)
- function moveStrangeLeafs()
- {
- var strangeLeafBox = document.getElementById('item-box-strangeLeaf');
- var brewingContainer = document.getElementById('tab-sub-container-brewing');
- brewingContainer.appendChild(strangeLeafBox);
- // remove event listeners before binding the tooltip to it
- var $strangeLeafBox = window.$(strangeLeafBox);
- $strangeLeafBox.off('mouseover').off('mouseleave');
- strangeLeafBox.title = '';
- // bind tooltip to item box
- ensureTooltip('ingredient-secondary', strangeLeafBox);
- // change color
- var color1 = '#800080';
- var color2 = '#990099';
- strangeLeafBox.style.background = 'linear-gradient(' + color1 + ', ' + color2 + ')';
- $strangeLeafBox
- .mouseover(function ()
- {
- strangeLeafBox.style.background = 'none';
- strangeLeafBox.style.backgroundColor = color2;
- })
- .mouseleave(function ()
- {
- strangeLeafBox.style.background = 'linear-gradient(' + color1 + ', ' + color2 + ')';
- });
- }
- // fix height of map item
- function fixTreasureMap()
- {
- var mapBox = document.getElementById('item-box-treasureMap');
- var numSpan = mapBox.lastElementChild;
- numSpan.style.display = '';
- numSpan.style.visibility = 'hidden';
- }
- // fix wobbling tree places on hover (in wood cutting)
- function fixWoodcutting()
- {
- addStyle("\nimg.woodcutting-tree-img\n{\n\tborder: 1px solid transparent;\n}\n\t\t");
- }
- // fix wobbling quest rows on hover (in quest book)
- function fixQuestBook()
- {
- addStyle("\n#table-quest-list tr\n{\n\tborder: 1px solid transparent;\n}\n\t\t");
- }
- function fixScrollImages()
- {
- function fixIcon(icon)
- {
- return icon + (icon != 'none' && !/\..{3,4}$/.test(icon) ? '.png' : '');
- }
- var _scrollTextHitSplat = window.scrollTextHitSplat;
- window.scrollTextHitSplat = function (icon, color, text, elId, cbType)
- {
- _scrollTextHitSplat(fixIcon(icon), color, text, elId, cbType);
- };
- var _scrollText = window.scrollText;
- window.scrollText = function (icon, color, text)
- {
- _scrollText(fixIcon(icon), color, text);
- };
- }
- function fixQuest8BraveryRecipe()
- {
- observer.add([
- 'quest8'
- , 'braveryPotion'
- ], function ()
- {
- var show = window.quest8 > 0 && window.braveryPotion == 0;
- var recipe = document.getElementById('brewing-braveryPotion');
- if (recipe)
- {
- recipe.style.display = show ? '' : 'none';
- }
- });
- }
- function fixHitText()
- {
- window.scrollTextHitSplat = function (icon, color, text, elId, cbType)
- {
- var imgTag = icon != 'none' ? "<img src=\"images/" + icon + "\" class=\"image-icon-50\" />" : '';
- var elementChosen = document.getElementById(elId);
- if (!elementChosen)
- {
- return;
- }
- var rect = elementChosen.getBoundingClientRect();
- var xCoord = (rect.left + rect.right) / 2;
- var yCoord = (rect.bottom + rect.top) / 2;
- var extraStyle = '';
- if (cbType == 'melee')
- {
- extraStyle = 'border: 1px solid red; background-color: #4d0000;';
- }
- else if (cbType == 'heal')
- {
- extraStyle = 'border: 1px solid green; background-color: lime;';
- }
- var $elementToAppend = window.$("<div class=\"scroller\" style=\"" + extraStyle + " color: " + color + "; position: fixed;\">" + imgTag + text + "</div>").appendTo('body');
- if (xCoord == 0 && yCoord == 0)
- {
- var tab = document.getElementById('tab-container-bar-combat');
- var tabRect = tab.getBoundingClientRect();
- var boxRect = $elementToAppend.get(0).getBoundingClientRect();
- xCoord = elId == 'img-hero' ? (tabRect.left - boxRect.width) : tabRect.right;
- yCoord = tabRect.top;
- }
- $elementToAppend
- .css(
- {
- left: xCoord
- , top: yCoord
- })
- .animate(
- {
- top: '-=50px'
- }, function ()
- {
- return $elementToAppend.fadeOut(1000, function ()
- {
- return $elementToAppend.remove();
- });
- });
- };
- }
- function fixBoatTooltips()
- {
- var boatBox = document.getElementById('item-box-boundRowBoat');
- var boatTooltip = boatBox && document.getElementById(boatBox.dataset.tooltipId || '');
- var canoeBox = document.getElementById('item-box-boundCanoe');
- if (!boatBox || !canoeBox || !boatTooltip)
- {
- return;
- }
- var canoeTooltip = boatTooltip.cloneNode(true);
- canoeTooltip.id = 'tooltip-boundCanoe';
- var header = canoeTooltip.firstElementChild;
- header.textContent = 'Canoe';
- boatTooltip.parentElement.appendChild(canoeTooltip);
- canoeBox.dataset.tooltipId = 'tooltip-boundCanoe';
- boatTooltip.appendChild(document.createElement('br'));
- var boatDuration = document.createElement('span');
- boatDuration.innerHTML = '<strong>Trip duration:</strong> 3 hours';
- boatTooltip.appendChild(boatDuration);
- canoeTooltip.appendChild(document.createElement('br'));
- var canoeDuration = document.createElement('span');
- canoeDuration.innerHTML = '<strong>Trip duration:</strong> 6 hours';
- canoeTooltip.appendChild(canoeDuration);
- }
- function fixAlignments()
- {
- addStyle("\n#item-box-special-case-questsUnlocked > img.image-icon-20\n{\n\tmargin-top: -1px;\n}\n\n#tab-container-crafting .settings-container\n{\n\tmargin: 5px 30px;\n}\n#table-crafting-recipe,\n#table-brewing-recipe,\n#table-magic-recipe\n{\n\twidth: calc(100% - 2*20px - 2*10px);\n}\n#tab-sub-container-magic-items\n{\n\tmargin: 5px 0px;\n}\n#table-magic-recipe\n{\n\twidth: calc(100% - 2*10px);\n}\n\n#tab-container-farming\n{\n\tpadding: 0 20px;\n}\n#tab-sub-container-farming\n{\n\tmargin: 5px 0;\n\tmargin-bottom: -10px;\n}\ndiv.farming-patch,\ndiv.farming-patch-locked\n{\n\tmargin: 10px;\n}\n\n#combat-table-area\n{\n\tborder-spacing: 0;\n}\n#combat-table-area > tbody > tr > td\n{\n\tvertical-align: top;\n}\ndiv#hero-area.hero,\ndiv#monster-area.monster\n{\n\tmargin-left: 20px;\n\tmargin-right: 20px;\n\tmargin-top: 10px;\n}\ntable.table-hero-stats,\ndiv.hp-bar,\n#hero-area div.fight-spellbook\n{\n\tmargin-left: 0;\n}\ndiv.hp-bar\n{\n\tmin-width: calc(100% - 2px);\n}\n#hero-area span.fight-spell\n{\n\tmargin-bottom: 0;\n\tmargin-top: 0;\n}\n#hero-area span.fight-spell:first-child\n{\n\tmargin-left: 0;\n}\n#hero-area span.fight-spell:last-child\n{\n\tmargin-right: 0;\n}\n#hero-area > div:last-child,\n.imageMonster\n{\n\theight: 556px !important;\n\tmargin-top: -50px;\n}\n#monster-area div.hp-bar\n{\n\tmargin-top: 66px;\n\tmargin-bottom: 74px;\n}\n#monster-area > br:first-child,\n#monster-area table.table-hero-stats + br\n{\n\tdisplay: none;\n}\n.imageMonster\n{\n\talign-items: flex-end;\n\tdisplay: flex;\n\tposition: relative;\n}\n#combat-table-area[style$=\"auto;\"]\n{\n\tborder-color: transparent;\n}\n#img-monster\n{\n\tposition: absolute;\n}\n#img-monster[src$=\"/1.png\"]\n{\n\theight: 250px;\n}\n#img-monster[src$=\"/2.png\"]\n{\n\ttransform: translateY(30px);\n}\n#img-monster[src$=\"/3.png\"]\n{\n\theight: 180px;\n\ttransform: translateY(-350px);\n}\n#img-monster[src$=\"/4.png\"]\n{\n\theight: 180px;\n}\n#img-monster[src$=\"/5.png\"]\n{\n\theight: 700px;\n\ttransform: translateY(130px);\n}\n#img-monster[src$=\"/7.png\"]\n{\n\theight: 450px;\n\ttransform: translateY(30px);\n}\n#img-monster[src$=\"/8.png\"]\n{\n\theight: 280px;\n\ttransform: translateY(-260px);\n}\n#img-monster[src$=\"/9.png\"]\n{\n\theight: 450px;\n\ttransform: translateY(-10px);\n}\n#img-monster[src$=\"/11.png\"],\n#img-monster[src$=\"/15.png\"]\n{\n\ttransform: translateY(-180px);\n}\n#img-monster[src$=\"/14.png\"]\n{\n\theight: 500px;\n\tmargin-left: -50px;\n\tmargin-right: -50px;\n}\n#img-monster[src$=\"/100.png\"]\n{\n\theight: 300px;\n}\n#img-monster[src$=\"/101.png\"]\n{\n\ttransform: translateY(-10px);\n}\n#tab-sub-container-combat > .large-button > .image-icon-50\n{\n\theight: 70px;\n\tmargin-top: -10px;\n\twidth: 70px;\n}\n#combat-table-area span.large-button,\n#combat-table-area span.medium-button\n{\n\tmargin: 10px;\n}\n#combat-table-area span.medium-button + br + br\n{\n\tdisplay: none;\n}\n\t\t");
- }
- function addHeroStatTooltips()
- {
- var table = document.querySelector('#hero-area table.table-hero-stats');
- if (!table)
- {
- return;
- }
- var statRow = table.rows.item(0);
- var attackCell = statRow.cells.item(0);
- attackCell.title = 'Attack Damage';
- window.$(attackCell).tooltip();
- var accuracyCell = statRow.cells.item(1);
- accuracyCell.title = 'Attack Accuracy';
- window.$(accuracyCell).tooltip();
- var speedCell = statRow.cells.item(2);
- speedCell.title = 'Attack Speed';
- window.$(speedCell).tooltip();
- var defenseCell = statRow.cells.item(3);
- defenseCell.title = 'Defense';
- window.$(defenseCell).tooltip();
- }
- function unifyTooltips()
- {
- function getLastNonEmptyChild(parent)
- {
- for (var i = parent.childNodes.length - 1; i >= 0; i--)
- {
- var child = parent.childNodes.item(i);
- if (child.nodeType === Node.TEXT_NODE
- && (child.textContent || '').trim() !== '')
- {
- return null;
- }
- else if (child.nodeType === Node.ELEMENT_NODE)
- {
- return child;
- }
- }
- return null;
- }
- // clean unnecessary br-tags in tooltips
- var tooltips = document.querySelectorAll('#tooltip-list > div[id^="tooltip-"]');
- for (var i = 0; i < tooltips.length; i++)
- {
- var tooltip = tooltips[i];
- var lneChild = void 0;
- while ((lneChild = getLastNonEmptyChild(tooltip)) && lneChild.tagName == 'BR')
- {
- tooltip.removeChild(lneChild);
- }
- }
- function getTooltip(item)
- {
- return document.getElementById('tooltip-' + item);
- }
- var boldify = [
- 'oilBarrel'
- , 'boundEmptyPickaxe'
- , 'boundEmptyShovel'
- , 'boundEmptyChisel'
- , 'ashes'
- , 'iceBones'
- ];
- var lastDotRegex = /\.\s*$/;
- for (var _i = 0, boldify_1 = boldify; _i < boldify_1.length; _i++)
- {
- var item = boldify_1[_i];
- var tooltip = getTooltip(item);
- if (!tooltip)
- {
- continue;
- }
- var textNode = tooltip.lastChild;
- while (textNode && (textNode.nodeType != Node.TEXT_NODE || (textNode.textContent || '').trim() === ''))
- {
- textNode = textNode.previousSibling;
- }
- if (!textNode)
- {
- continue;
- }
- var text = textNode.textContent || '';
- var split = text.split(/\.(?=\s*\S+)/);
- var clickText = split[split.length - 1];
- textNode.textContent = text.replace(clickText, '');
- if (split.length > 1)
- {
- tooltip.appendChild(document.createElement('br'));
- tooltip.appendChild(document.createElement('br'));
- }
- var boldText = document.createElement('b');
- boldText.textContent = clickText;
- tooltip.appendChild(boldText);
- }
- function prepareTooltip(item, editText, createOnMissing)
- {
- if (createOnMissing === void 0)
- {
- createOnMissing = false;
- }
- var tooltip = getTooltip(item);
- if (!tooltip)
- {
- return;
- }
- // try to find the b-node:
- var bNode = getLastNonEmptyChild(tooltip);
- if (bNode && bNode.tagName === 'SPAN')
- {
- bNode = getLastNonEmptyChild(bNode);
- }
- if (!bNode || bNode.tagName !== 'B')
- {
- if (!createOnMissing)
- {
- bNode = null;
- }
- else
- {
- tooltip.appendChild(document.createElement('br'));
- tooltip.appendChild(document.createElement('br'));
- bNode = document.createElement('b');
- tooltip.appendChild(bNode);
- }
- }
- if (bNode)
- {
- bNode.textContent = editText(bNode);
- }
- }
- // remove dots
- for (var i = 0; i < tooltips.length; i++)
- {
- var item = tooltips.item(i).id.replace(/^tooltip-/, '');
- prepareTooltip(item, function (bNode)
- {
- var text = bNode.textContent || '';
- if (/Click to /.test(text))
- {
- return text.replace(lastDotRegex, '');
- }
- return text;
- });
- }
- // add click texts
- function setText(item, text)
- {
- prepareTooltip(item, function ()
- {
- return text;
- }, true);
- }
- for (var _a = 0, FURNACE_LEVELS_1 = FURNACE_LEVELS; _a < FURNACE_LEVELS_1.length; _a++)
- {
- var furnaceLevel = FURNACE_LEVELS_1[_a];
- var furnaceItem = getBoundKey(furnaceLevel + 'Furnace');
- setText(furnaceItem, 'Click to operate');
- var ovenItem = getBoundKey(furnaceLevel + 'Oven');
- setText(ovenItem, 'Click to operate');
- }
- // fix tooltip of quests-book
- var questBookTooltip = getTooltip('quests-book');
- if (questBookTooltip)
- {
- var childNodes = questBookTooltip.childNodes;
- for (var i = 0; i < childNodes.length; i++)
- {
- var node = childNodes[i];
- if (node.nodeType === Node.TEXT_NODE
- && (node.textContent || '').indexOf('Click to see a list of quests.') > -1)
- {
- var next = node.nextSibling;
- if (next)
- {
- questBookTooltip.removeChild(next);
- }
- questBookTooltip.removeChild(node);
- }
- }
- }
- // fix tooltip of axe
- var axeTooltip = getTooltip('boundEmptyAxe');
- if (axeTooltip)
- {
- axeTooltip.insertBefore(document.createElement('br'), axeTooltip.lastElementChild);
- }
- var texts = {
- 'quests-book': 'Click to see a list of quests'
- , 'rake': 'Click to upgrade your rake'
- , 'boundBoat': 'Click to send boat'
- , 'boundCanoe': 'Click to send boat'
- };
- for (var item in texts)
- {
- setText(item, texts[item]);
- }
- }
- var cached = {
- scrollWidth: 0
- , scrollHeight: 0
- };
- function changeTooltipPosition(event)
- {
- var tooltipX = event.pageX - 8;
- var tooltipY = event.pageY + 8;
- var el = document.querySelector('body > div.tooltip');
- if (!el)
- {
- return;
- }
- if (!this)
- {
- // init
- cached.scrollWidth = document.body.scrollWidth;
- cached.scrollHeight = document.body.scrollHeight;
- }
- var rect = el.getBoundingClientRect();
- var css = {
- left: tooltipX
- , top: tooltipY
- , width: ''
- , height: ''
- , maxWidth: cached.scrollWidth
- , maxHeight: cached.scrollHeight
- };
- var diffX = cached.scrollWidth - 20 - tooltipX - rect.width;
- if (diffX < 0)
- {
- css.left += diffX;
- css.width = rect.width - 42;
- }
- var diffY = cached.scrollHeight - 20 - tooltipY - rect.height;
- if (diffY < 0)
- {
- css.top += diffY;
- css.height = rect.height - 22;
- }
- window.$(el).css(css);
- }
- function fixTooltipPositioning()
- {
- window.changeTooltipPosition = changeTooltipPosition;
- window.loadTooltips();
- }
- // fix tooltips of some food items
- function fixTooltips()
- {
- var foodTooltipTemplate = document.getElementById('tooltip-uncookedBread');
- if (!foodTooltipTemplate)
- {
- return;
- }
- function ensureTooltip(item, tooltipTemplate, onCreate)
- {
- var tooltipId = 'tooltip-' + item;
- if (document.getElementById(tooltipId) != null)
- {
- return;
- }
- var newTooltip = tooltipTemplate.cloneNode(true);
- newTooltip.id = tooltipId;
- onCreate(newTooltip);
- tooltipTemplate.parentElement.appendChild(newTooltip);
- }
- function ensureFoodTooltip(key, title, energyAmount)
- {
- ensureTooltip(key, foodTooltipTemplate, function (newTooltip)
- {
- var spans = newTooltip.getElementsByTagName('span');
- var titleSpan = spans[0];
- var energyNode = spans[1].firstChild;
- titleSpan.textContent = title;
- energyNode.textContent = '+'
- + (typeof energyAmount === 'string' ? energyAmount : format.number(energyAmount))
- + ' ';
- });
- }
- ensureFoodTooltip('uncookedCarrotCake', 'Uncooked Carrot Cake', 400);
- ensureFoodTooltip('carrotCake', 'Carrot Cake', 400);
- ensureFoodTooltip('uncookedPizza', 'Uncooked Pizza', 1000);
- ensureFoodTooltip('pizza', 'Pizza', 1000);
- ensureFoodTooltip('carrotSoup', 'Carrot Soup', 300);
- ensureFoodTooltip('tomatoSoup', 'Tomato Soup', 600);
- ensureFoodTooltip('salad', 'Salad', 1100);
- }
- function init()
- {
- fixClientGameLoop();
- fixScroller();
- fixTooltipStyle();
- fixRefreshingMagicRecipes();
- moveStrangeLeafs();
- fixTreasureMap();
- fixWoodcutting();
- fixQuestBook();
- // apply fix for scroll images later to fix images in this code too
- fixHitText();
- fixScrollImages();
- fixQuest8BraveryRecipe();
- fixBoatTooltips();
- fixAlignments();
- addHeroStatTooltips();
- unifyTooltips();
- fixTooltipPositioning();
- fixTooltips();
- }
- temporaryFixes.init = init;
- })(temporaryFixes || (temporaryFixes = {}));
- /**
- * improve timer
- */
- var timer;
- (function (timer)
- {
- timer.name = 'timer';
- function bindNewFormatter()
- {
- function doBind()
- {
- window.formatTime = window.formatTimeShort = window.formatTimeShort2 = function (seconds)
- {
- return format.timer(seconds);
- };
- }
- window.addEventListener('load', function ()
- {
- return setTimeout(function ()
- {
- return doBind();
- }, 100);
- });
- doBind();
- setTimeout(function ()
- {
- return doBind();
- }, 100);
- }
- function improveSmeltingTimer()
- {
- addStyle("\n#notif-smelting > span:not(.timer)\n{\n\tdisplay: none;\n}\n\t\t");
- var smeltingNotifBox = document.getElementById('notif-smelting');
- var smeltingTimerEl = document.createElement('span');
- smeltingTimerEl.className = 'timer';
- smeltingNotifBox.appendChild(smeltingTimerEl);
- var smeltingInterval;
- function updatePercValues()
- {
- if (smeltingInterval)
- {
- window.clearInterval(smeltingInterval);
- }
- var delta = 0;
- smeltingInterval = window.setInterval(function ()
- {
- return updateSmeltingTimer(++delta);
- }, 1000);
- updateSmeltingTimer();
- }
- function updateSmeltingTimer(delta)
- {
- if (delta === void 0)
- {
- delta = 0;
- }
- var totalTime = window.smeltingPercD;
- // thanks at /u/marcus898 for your bug report
- var elapsedTime = Math.round(window.smeltingPerc * totalTime / 100) + delta;
- smeltingTimerEl.textContent = format.timer(Math.max(totalTime - elapsedTime, 0));
- }
- observer.add('smeltingPercD', function ()
- {
- return updatePercValues();
- });
- observer.add('smeltingPerc', function ()
- {
- return updatePercValues();
- });
- updatePercValues();
- }
- function improveTimer(cssRulePrefix, textColor, timerColor, infoIdPrefx, containerPrefix, updateFn)
- {
- addStyle("\n/* hide built in timer elements */\n" + cssRulePrefix + " > *:not(img):not(.info)\n{\n\tdisplay: none;\n}\n" + cssRulePrefix + " > div.info\n{\n\tcolor: " + textColor + ";\n\tmargin-top: 5px;\n\tpointer-events: none;\n\ttext-align: center;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n}\n" + cssRulePrefix + " > div.info > div.name\n{\n\tfont-size: 1.2rem;\n}\n" + cssRulePrefix + " > div.info > div.timer\n{\n\tcolor: " + timerColor + ";\n}\n\t\t");
- for (var i = 0; i < 6; i++)
- {
- var num = i + 1;
- var infoId = infoIdPrefx + num;
- var container = document.getElementById(containerPrefix + num);
- container.style.position = 'relative';
- var infoEl = document.createElement('div');
- infoEl.className = 'info';
- infoEl.id = infoId;
- infoEl.innerHTML = "<div class=\"name\"></div><div class=\"timer\"></div>";
- container.appendChild(infoEl);
- updateFn(num, infoId, true);
- }
- }
- function updateTreeInfo(placeId, infoElId, init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var infoEl = document.getElementById(infoElId);
- var nameEl = infoEl.firstElementChild;
- var timerEl = infoEl.lastElementChild;
- var idKey = 'treeId' + placeId;
- var growTimerKey = 'treeGrowTimer' + placeId;
- var lockedKey = 'treeUnlocked' + placeId;
- var treeId = getGameValue(idKey);
- if (treeId == 0)
- {
- var isLocked = placeId > 4 && getGameValue(lockedKey) == 0;
- nameEl.textContent = isLocked ? 'Locked' : 'Empty';
- timerEl.textContent = '';
- }
- else
- {
- nameEl.textContent = key2Name(window.getTreeName(treeId)) || 'Unknown Tree';
- var remainingTime = window.TREE_GROW_TIME[treeId - 1] - getGameValue(growTimerKey);
- timerEl.textContent = remainingTime > 0 ? '(' + format.timer(remainingTime) + ')' : 'Fully grown';
- }
- if (init)
- {
- observer.add([idKey, growTimerKey, lockedKey], function ()
- {
- return updateTreeInfo(placeId, infoElId, false);
- });
- }
- }
- // add tree grow timer
- function improveTreeGrowTimer()
- {
- improveTimer('.woodcutting-tree', 'white', 'yellow', 'wc-tree-info-', 'wc-div-tree-', updateTreeInfo);
- }
- function updatePatchInfo(patchId, infoElId, init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var infoEl = document.getElementById(infoElId);
- var nameEl = infoEl.querySelector('.name');
- var timerEl = infoEl.querySelector('.timer');
- var idKey = 'farmingPatchSeed' + patchId;
- var growTimeKey = 'farmingPatchGrowTime' + patchId;
- var timerKey = 'farmingPatchTimer' + patchId;
- var stageKey = 'farmingPatchStage' + patchId;
- var stage = getGameValue(stageKey);
- var seedName = PLANT_NAME[getGameValue(idKey)] || 'Unkown Plant';
- if (stage == 0)
- {
- var isLocked = patchId > 4 && window.donorFarmingPatch == 0;
- nameEl.textContent = isLocked ? 'Locked' : 'Click to grow';
- timerEl.textContent = '';
- }
- else if (stage >= 4)
- {
- nameEl.textContent = stage > 4 ? 'Dead Plant' : seedName;
- timerEl.textContent = stage > 4 ? 'Click to remove' : 'Click to harvest';
- }
- else
- {
- nameEl.textContent = seedName;
- var remainingTime = getGameValue(growTimeKey) - getGameValue(timerKey);
- timerEl.textContent = '(' + format.timer(remainingTime) + ')';
- }
- if (init)
- {
- observer.add([idKey, timerKey, stageKey, 'donorFarmingPatch'], function ()
- {
- return updatePatchInfo(patchId, infoElId, false);
- });
- }
- }
- // add seed name and change color of timer
- function improveSeedGrowTimer()
- {
- improveTimer('div[id^="farming-patch-area-"]', 'black', 'blue', 'farming-patch-info-', 'farming-patch-area-', updatePatchInfo);
- }
- function init()
- {
- bindNewFormatter();
- improveSmeltingTimer();
- improveTreeGrowTimer();
- improveSeedGrowTimer();
- }
- timer.init = init;
- })(timer || (timer = {}));
- /**
- * improve smelting dialog
- */
- var smelting;
- (function (smelting)
- {
- smelting.name = 'smelting';
- var TIME_NEEDED_ID = 'smelting-time-needed';
- var LAST_SMELTING_AMOUNT_KEY = 'lastSmeltingAmount';
- var LAST_SMELTING_BAR_KEY = 'lastSmeltingBar';
- var smeltingValue = null;
- var amountInput;
- function prepareAmountInput()
- {
- amountInput = document.getElementById('input-smelt-bars-amount');
- amountInput.type = 'number';
- amountInput.min = '0';
- amountInput.step = '5';
- function onValueChange()
- {
- smeltingValue = null;
- window.selectBar('', null, amountInput, document.getElementById('smelting-furnace-capacity').value);
- }
- amountInput.addEventListener('mouseup', onValueChange);
- amountInput.addEventListener('keyup', onValueChange);
- amountInput.setAttribute('onkeyup', '');
- }
- function setBarCap(bar, capacity)
- {
- if (bar == '')
- {
- bar = window.selectedBar;
- }
- var requirements = SMELTING_REQUIREMENTS[bar];
- var maxAmount = parseInt(capacity, 10);
- for (var key in requirements)
- {
- var req = requirements[key];
- maxAmount = Math.min(Math.floor(getGameValue(key) / req), maxAmount);
- }
- var value = parseInt(amountInput.value, 10);
- if (value > maxAmount)
- {
- smeltingValue = value;
- amountInput.value = maxAmount.toString();
- }
- else if (smeltingValue != null)
- {
- amountInput.value = Math.min(smeltingValue, maxAmount).toString();
- if (smeltingValue <= maxAmount)
- {
- smeltingValue = null;
- }
- }
- }
- function prepareTimeNeeded()
- {
- var neededMatsEl = document.getElementById('dialogue-furnace-mats-needed');
- var parent = neededMatsEl && neededMatsEl.parentElement;
- if (!neededMatsEl || !parent)
- {
- return;
- }
- var br = document.createElement('br');
- var timeBox = document.createElement('div');
- timeBox.className = 'basic-smallbox';
- timeBox.innerHTML = "<img src=\"images/icons/hourglass.png\" class=\"image-icon-30\">\n\t\tDuration: <span id=\"" + TIME_NEEDED_ID + "\"></span>";
- var next = neededMatsEl.nextElementSibling;
- parent.insertBefore(br, next);
- parent.insertBefore(timeBox, next);
- }
- function updateTimeNeeded(value)
- {
- var timeEl = document.getElementById(TIME_NEEDED_ID);
- if (!timeEl)
- {
- return;
- }
- var num = parseInt(value, 10);
- var timePerBar = window.getTimerPerBar(window.selectedBar);
- timeEl.textContent = format.timer(timePerBar * num);
- }
- function init()
- {
- prepareAmountInput();
- prepareTimeNeeded();
- var _selectBar = window.selectBar;
- var updateSmeltingRequirements = function (bar, inputElement, inputBarsAmountEl, capacity)
- {
- _selectBar(bar, inputElement, inputBarsAmountEl, capacity);
- updateTimeNeeded(inputBarsAmountEl.value);
- };
- window.selectBar = function (bar, inputElement, inputBarsAmountEl, capacity)
- {
- setBarCap(bar, capacity);
- // save selected bar
- if (bar != '')
- {
- store.set(LAST_SMELTING_BAR_KEY, bar);
- }
- // save amount
- store.set(LAST_SMELTING_AMOUNT_KEY, inputBarsAmountEl.value);
- updateSmeltingRequirements(bar, inputElement, inputBarsAmountEl, capacity);
- };
- var lastBar = store.get(LAST_SMELTING_BAR_KEY);
- var lastAmount = store.get(LAST_SMELTING_AMOUNT_KEY);
- var _openFurnaceDialogue = window.openFurnaceDialogue;
- window.openFurnaceDialogue = function (furnace)
- {
- var capacity = window.getFurnaceCapacity(furnace);
- if (window.smeltingBarType == 0)
- {
- amountInput.max = capacity.toString();
- }
- // restore amount
- var inputBarsAmountEl = document.getElementById('input-smelt-bars-amount');
- if (inputBarsAmountEl && inputBarsAmountEl.value == '-1' && lastAmount != null)
- {
- inputBarsAmountEl.value = lastAmount;
- }
- _openFurnaceDialogue(furnace);
- // restore selected bar
- if ((!window.selectedBar || window.selectedBar == 'none') && lastBar != null)
- {
- window.selectedBar = lastBar;
- }
- // update whether requirements are fulfilled
- var barInputId = 'input-furnace-' + split2Words(window.selectedBar, '-').toLowerCase();
- var inputElement = document.getElementById(barInputId);
- if (inputElement && inputBarsAmountEl)
- {
- updateSmeltingRequirements(window.selectedBar, inputElement, inputBarsAmountEl, capacity.toString());
- }
- };
- }
- smelting.init = init;
- })(smelting || (smelting = {}));
- /**
- * add chance to time calculator
- */
- var fishingInfo;
- (function (fishingInfo)
- {
- fishingInfo.name = 'fishingInfo';
- /**
- * calculates the number of seconds until the event with the given chance happened at least once with the given
- * probability p (in percent)
- */
- function calcSecondsTillP(chancePerSecond, p)
- {
- return Math.round(Math.log(1 - p / 100) / Math.log(1 - chancePerSecond));
- }
- function addChanceTooltip(headline, chancePerSecond, elId, targetEl)
- {
- // ensure tooltip exists and is correctly binded
- var tooltipEl = ensureTooltip('chance-' + elId, targetEl);
- // set elements content
- var percValues = [1, 10, 20, 50, 80, 90, 99];
- var percRows = '';
- for (var _i = 0, percValues_1 = percValues; _i < percValues_1.length; _i++)
- {
- var p = percValues_1[_i];
- percRows += "\n\t\t\t\t<tr>\n\t\t\t\t\t<td>" + p + "%</td>\n\t\t\t\t\t<td>" + format.time2NearestUnit(calcSecondsTillP(chancePerSecond, p), true) + "</td>\n\t\t\t\t</tr>";
- }
- tooltipEl.innerHTML = "<h2>" + headline + "</h2>\n\t\t\t<table class=\"chance\">\n\t\t\t\t<tr>\n\t\t\t\t\t<th>Probability</th>\n\t\t\t\t\t<th>Time</th>\n\t\t\t\t</tr>\n\t\t\t\t" + percRows + "\n\t\t\t</table>\n\t\t";
- }
- function addChanceStyle()
- {
- addStyle("\ntable.chance\n{\n\tborder-spacing: 0;\n}\ntable.chance th\n{\n\tborder-bottom: 1px solid gray;\n}\ntable.chance td:first-child\n{\n\tborder-right: 1px solid gray;\n\ttext-align: center;\n}\ntable.chance th,\ntable.chance td\n{\n\tpadding: 4px 8px;\n}\ntable.chance tr:nth-child(2n) td\n{\n\tbackground-color: white;\n}\n\t\t");
- }
- function addXp()
- {
- var table = document.querySelector('#dialogue-id-fishingRod table');
- if (!table)
- {
- return;
- }
- var rows = table.rows;
- for (var i = 0; i < rows.length; i++)
- {
- var row = rows.item(i);
- if (row.classList.contains('xp-added'))
- {
- continue;
- }
- if (i == 0)
- {
- var xpCell = document.createElement('th');
- xpCell.textContent = 'XP';
- row.appendChild(xpCell);
- }
- else
- {
- var cell = row.insertCell(-1);
- var rawFish = row.id.replace('dialogue-fishing-rod-tr-', '');
- var xp = FISH_XP[rawFish];
- cell.textContent = xp == null ? '?' : format.number(xp);
- }
- row.classList.add('xp-added');
- }
- }
- function chance2TimeCalculator()
- {
- var fishList = ['shrimp', 'sardine', 'tuna', 'swordfish', 'shark'];
- for (var _i = 0, fishList_1 = fishList; _i < fishList_1.length; _i++)
- {
- var fish = fishList_1[_i];
- var rawFish = 'raw' + capitalize(fish);
- var row = document.getElementById('dialogue-fishing-rod-tr-' + rawFish);
- if (!row)
- {
- continue;
- }
- var chanceCell = row.cells.item(4);
- var chance = (chanceCell.textContent || '')
- .replace(/[^\d\/]/g, '')
- .split('/')
- .reduce(function (p, c)
- {
- return p / parseInt(c, 10);
- }, 1);
- addChanceTooltip("One raw " + fish + " at least every:", chance, rawFish, row);
- }
- }
- function init()
- {
- addChanceStyle();
- var _clicksShovel = window.clicksShovel;
- window.clicksShovel = function ()
- {
- _clicksShovel();
- var shovelChance = document.getElementById('dialogue-shovel-chance');
- var titleEl = shovelChance.parentElement;
- var chance = 1 / window.getChanceOfDiggingSand();
- addChanceTooltip('One sand at least every:', chance, 'shovel', titleEl);
- };
- // depends on fishingXp
- var _clicksFishingRod = window.clicksFishingRod;
- window.clicksFishingRod = function ()
- {
- _clicksFishingRod();
- addXp();
- chance2TimeCalculator();
- };
- }
- fishingInfo.init = init;
- })(fishingInfo || (fishingInfo = {}));
- /**
- * add tooltips for recipes
- */
- var recipeTooltips;
- (function (recipeTooltips)
- {
- recipeTooltips.name = 'recipeTooltips';
- function updateRecipeTooltips(recipeKey, recipes)
- {
- var table = document.getElementById('table-' + recipeKey + '-recipe');
- var rows = table.rows;
- function recipe2Title(recipe)
- {
- return recipe.recipe
- .map(function (name, i)
- {
- return format.number(recipe.recipeCost[i]) + ' '
- + split2Words(name).toLowerCase();
- })
- .join(' + ');
- };
- for (var i = 1; i < rows.length; i++)
- {
- var row = rows.item(i);
- var key = row.id.replace(recipeKey + '-', '');
- var recipe = recipes[key];
- var requirementCell = row.cells.item(3);
- requirementCell.title = recipe2Title(recipe);
- window.$(requirementCell).tooltip();
- }
- }
- function updateTooltipsOnReinitRecipes(key)
- {
- var capitalKey = capitalize(key);
- var processKey = 'process' + capitalKey + 'Tab';
- var _processTab = window[processKey];
- window[processKey] = function ()
- {
- var reinit = !!getGameValue('refreshLoad' + capitalKey + 'Table');
- _processTab();
- if (reinit)
- {
- updateRecipeTooltips(key, getGameValue(key + 'Recipes'));
- }
- };
- }
- function init()
- {
- updateTooltipsOnReinitRecipes('crafting');
- updateTooltipsOnReinitRecipes('brewing');
- updateTooltipsOnReinitRecipes('magic');
- updateTooltipsOnReinitRecipes('cooksBook');
- }
- recipeTooltips.init = init;
- })(recipeTooltips || (recipeTooltips = {}));
- /**
- * fix formatting of numbers
- */
- var fixNumbers;
- (function (fixNumbers)
- {
- fixNumbers.name = 'fixNumbers';
- function prepareRecipeForTable(recipe)
- {
- // create a copy of the recipe to prevent requirement check from failing
- var newRecipe = JSON.parse(JSON.stringify(recipe));
- newRecipe.recipeCost = recipe.recipeCost.map(function (cost)
- {
- return format.number(cost);
- });
- newRecipe.xp = format.number(recipe.xp);
- return newRecipe;
- }
- function fixNumberFormat()
- {
- var _addRecipeToBrewingTable = window.addRecipeToBrewingTable;
- window.addRecipeToBrewingTable = function (brewingRecipe)
- {
- _addRecipeToBrewingTable(prepareRecipeForTable(brewingRecipe));
- };
- var _addRecipeToMagicTable = window.addRecipeToMagicTable;
- window.addRecipeToMagicTable = function (magicRecipe)
- {
- _addRecipeToMagicTable(prepareRecipeForTable(magicRecipe));
- };
- var tooltipList = document.querySelectorAll('#tooltip-list div[id^="tooltip-"][id$="Seeds"]');
- for (var i = 0; i < tooltipList.length; i++)
- {
- var tooltip = tooltipList[i];
- tooltip.innerHTML = format.numbersInText(tooltip.innerHTML);
- }
- var fightEnergyCells = document.querySelectorAll('#dialogue-fight tr > td:nth-child(4)');
- for (var i = 0; i < fightEnergyCells.length; i++)
- {
- var cell = fightEnergyCells[i];
- cell.innerHTML = format.numbersInText(cell.innerHTML);
- }
- }
- function init()
- {
- fixNumberFormat();
- }
- fixNumbers.init = init;
- })(fixNumbers || (fixNumbers = {}));
- /**
- * add slider for machines
- */
- var machineDialog;
- (function (machineDialog)
- {
- machineDialog.name = 'machineDialog';
- var $slider;
- function createSlider()
- {
- var br = document.querySelector('#dialogue-machinery-current-total ~ br');
- var parent = br && br.parentElement;
- if (!br || !parent)
- {
- return;
- }
- addStyle("\n#dialogue-id-boundMachinery .ui-slider\n{\n\tmargin: 10px 5px;\n}\n#dialogue-id-boundMachinery .ui-slider:not([data-owned=\"10\"])::after\n{\n\tbackground: hsla(0, 0%, 0%, 1);\n\tborder: 1px solid #c5c5c5;\n\tborder-radius: 3px;\n\tborder-top-left-radius: 0;\n\tborder-bottom-left-radius: 0;\n\tcontent: '';\n\tmargin-left: -3px;\n\tpadding-left: 3px;\n\theight: 100%;\n\twidth: 0%;\n\tposition: absolute;\n\tleft: 100%;\n\ttop: -1px;\n}\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"9\"] { width: calc((100% - 10px - 2px) / 10*9); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"9\"]::after { width: calc(100% / 9 * 1); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"8\"] { width: calc((100% - 10px - 2px) / 10*8); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"8\"]::after { width: calc(100% / 8 * 2); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"7\"] { width: calc((100% - 10px - 2px) / 10*7); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"7\"]::after { width: calc(100% / 7 * 3); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"6\"] { width: calc((100% - 10px - 2px) / 10*6); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"6\"]::after { width: calc(100% / 6 * 4); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"5\"] { width: calc((100% - 10px - 2px) / 10*5); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"5\"]::after { width: calc(100% / 5 * 5); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"4\"] { width: calc((100% - 10px - 2px) / 10*4); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"4\"]::after { width: calc(100% / 4 * 6); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"3\"] { width: calc((100% - 10px - 2px) / 10*3); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"3\"]::after { width: calc(100% / 3 * 7); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"2\"] { width: calc((100% - 10px - 2px) / 10*2); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"2\"]::after { width: calc(100% / 2 * 8); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"1\"] { width: calc((100% - 10px - 2px) / 10*1); }\n#dialogue-id-boundMachinery .ui-slider[data-owned=\"1\"]::after { width: calc(100% / 1 * 9); }\n\t\t");
- var slider = document.createElement('div');
- parent.insertBefore(slider, br);
- $slider = window.$(slider)
- .slider(
- {
- range: 'max'
- , min: 0
- , max: 10
- , value: 0
- , slide: function (event, ui)
- {
- return updateValue(ui.value);
- }
- });
- // hide br and up/down arrows
- br.style.display = 'none';
- var arrows = document.querySelectorAll('input[onclick^="turnOn("]');
- for (var i = 0; i < arrows.length; i++)
- {
- arrows[i].style.display = 'none';
- }
- var els = document.querySelectorAll('[onclick*="openMachineryDialogue("]');
- var boundMachineKeyList = [];
- for (var i = 0; i < els.length; i++)
- {
- var match = els[i].id.match(/openMachineryDialogue\('(.+?)'\)/);
- if (match)
- {
- boundMachineKeyList.push(getBoundKey(match[1]));
- }
- }
- observer.add(boundMachineKeyList, function ()
- {
- return updateMax();
- });
- }
- function updateMax()
- {
- var machineEl = document.getElementById('dialogue-machinery-chosen');
- if (machineEl && machineEl.value != '')
- {
- var boundMachineKey = getBoundKey(machineEl.value);
- var ownedNum = getGameValue(boundMachineKey);
- $slider.slider('option', 'max', ownedNum);
- $slider.get(0).dataset.owned = ownedNum.toString();
- }
- }
- function updateValue(value)
- {
- var typeEl = document.getElementById('dialogue-machinery-chosen');
- var numEl = document.getElementById('dialogue-machinery-current-on');
- if (numEl && typeEl)
- {
- var valueBefore = parseInt(numEl.textContent || '0', 10);
- var machine = typeEl.value;
- var increment = valueBefore < value;
- var diff = Math.abs(valueBefore - value);
- for (var i = 0; i < diff; i++)
- {
- window.turnOn(machine, increment);
- }
- }
- }
- function init()
- {
- createSlider();
- var _openMachineryDialogue = window.openMachineryDialogue;
- window.openMachineryDialogue = function (machineType)
- {
- _openMachineryDialogue(machineType);
- updateMax();
- $slider.slider('value', getGameValue(machineType + 'On'));
- };
- }
- machineDialog.init = init;
- })(machineDialog || (machineDialog = {}));
- /**
- * improve behaviour of amount inputs
- */
- var amountInputs;
- (function (amountInputs)
- {
- amountInputs.name = 'amountInputs';
- function getMax(recipe)
- {
- var max = Number.MAX_SAFE_INTEGER;
- for (var i = 0; i < recipe.recipe.length; i++)
- {
- max = Math.min(max, Math.floor(getGameValue(recipe.recipe[i]) / recipe.recipeCost[i]));
- }
- return max;
- }
- function setAmount(id, recipeCollection, key)
- {
- var numInput = document.getElementById(id);
- if (!numInput)
- {
- return;
- }
- var max = getMax(recipeCollection[key]);
- numInput.value = max.toString();
- numInput.select();
- }
- function init()
- {
- var _multiCraft = window.multiCraft;
- window.multiCraft = function (item)
- {
- _multiCraft(item);
- setAmount('dialogue-multicraft-input', window.craftingRecipes, item);
- };
- var _brew = window.brew;
- window.brew = function (potion)
- {
- _brew(potion);
- setAmount('dialogue-brewing-input', window.brewingRecipes, potion);
- };
- var _cooksBookInputDialogue = window.cooksBookInputDialogue;
- window.cooksBookInputDialogue = function (food)
- {
- _cooksBookInputDialogue(food);
- setAmount('dialogue-cooksBook-input', window.cooksBookRecipes, food);
- };
- }
- amountInputs.init = init;
- })(amountInputs || (amountInputs = {}));
- /**
- * improves the top bar
- */
- var newTopbar;
- (function (newTopbar)
- {
- newTopbar.name = 'newTopbar';
- var linkCell, tabCell, infoCell;
- var addQueues = {
- link: []
- , tab: []
- , info: []
- };
- function addLinkEntry(el)
- {
- if (!linkCell)
- {
- addQueues.link.push(el);
- }
- else
- {
- linkCell.appendChild(document.createTextNode('|'));
- linkCell.appendChild(el);
- }
- }
- newTopbar.addLinkEntry = addLinkEntry;
- function addTabEntry(el)
- {
- if (!tabCell)
- {
- addQueues.tab.push(el);
- }
- else
- {
- tabCell.appendChild(document.createTextNode('|'));
- tabCell.appendChild(el);
- }
- }
- newTopbar.addTabEntry = addTabEntry;
- function addInfoEntry(el)
- {
- if (!infoCell)
- {
- addQueues.info.push(el);
- }
- else
- {
- infoCell.appendChild(document.createTextNode('|'));
- infoCell.appendChild(el);
- }
- }
- newTopbar.addInfoEntry = addInfoEntry;
- function init()
- {
- addStyle("\ntable.top-links,\ntable.top-links *\n{\n\tpadding: 0;\n}\ntable.top-links td > *\n{\n\tdisplay: inline-block;\n\tpadding: 2px 6px;\n}\n\t\t");
- var table = document.querySelector('table.top-links');
- if (!table)
- {
- return;
- }
- var row = table.rows.item(0);
- var cells = row.cells;
- var tabIdx = [2, 4];
- var infoIdx = [5, 6];
- var newRow = table.insertRow(-1);
- linkCell = newRow.insertCell(-1);
- tabCell = newRow.insertCell(-1);
- tabCell.style.textAlign = 'center';
- infoCell = newRow.insertCell(-1);
- infoCell.style.textAlign = 'right';
- for (var i = 0; i < cells.length; i++)
- {
- var container = linkCell;
- if (tabIdx.indexOf(i) != -1)
- {
- container = tabCell;
- }
- else if (infoIdx.indexOf(i) != -1)
- {
- container = infoCell;
- }
- var cell = cells.item(i);
- var el = cell.firstElementChild;
- if (cell.childNodes.length > 1)
- {
- el = document.createElement('span');
- el.style.color = 'yellow';
- while (cell.childNodes.length > 0)
- {
- el.appendChild(cell.childNodes[0]);
- }
- }
- if (container.children.length > 0)
- {
- container.appendChild(document.createTextNode('|'));
- }
- if (el)
- {
- container.appendChild(el);
- }
- }
- var parent = row.parentElement;
- if (parent)
- {
- parent.removeChild(row);
- }
- for (var _i = 0, _a = addQueues.link; _i < _a.length; _i++)
- {
- var el = _a[_i];
- addLinkEntry(el);
- }
- for (var _b = 0, _c = addQueues.tab; _b < _c.length; _b++)
- {
- var el = _c[_b];
- addTabEntry(el);
- }
- for (var _d = 0, _e = addQueues.info; _d < _e.length; _d++)
- {
- var el = _e[_d];
- addInfoEntry(el);
- }
- var _openTab = window.openTab;
- window.openTab = function (newTab)
- {
- var oldTab = window.currentOpenTab;
- _openTab(newTab);
- var children = tabCell.children;
- for (var i = 0; i < children.length; i++)
- {
- var el = children[i];
- var match = (el.getAttribute('onclick') || '').match(/openTab\('([^']+)'\)/);
- if (!match)
- {
- continue;
- }
- var tab = match[1];
- if (oldTab == tab)
- {
- el.style.color = '';
- }
- if (newTab == tab)
- {
- el.style.color = 'white';
- }
- }
- };
- }
- newTopbar.init = init;
- })(newTopbar || (newTopbar = {}));
- /**
- * style tweaks
- */
- var styleTweaks;
- (function (styleTweaks)
- {
- styleTweaks.name = 'styleTweaks';
- function addTweakStyle(setting, style)
- {
- if (setting != '')
- {
- var prefix = setting == '' ? '' : 'body.' + setting;
- style = style.replace(/(^\s*|,\s*|\}\s*)([^\{\},]+)(,|\s*\{)/g, '$1' + prefix + ' $2$3');
- document.body.classList.add(setting);
- }
- addStyle(style, setting != '' ? setting : null);
- }
- // tweak oil production/consumption
- function tweakOil()
- {
- addTweakStyle('tweak-oil', "\nspan#oil-flow-values\n{\n\tmargin-left: .5em;\n\tpadding-left: 2rem;\n\tposition: relative;\n}\n#oil-flow-values > span:nth-child(-n+2)\n{\n\tfont-size: 0px;\n\tposition: absolute;\n\tleft: 0;\n\ttop: -0.75rem;\n\tvisibility: hidden;\n}\n#oil-flow-values > span:nth-child(-n+2) > span\n{\n\tfont-size: 1rem;\n\tvisibility: visible;\n}\n#oil-flow-values > span:nth-child(2)\n{\n\ttop: 0.75rem;\n}\n#oil-flow-values span[data-item-display=\"oilIn\"]::before\n{\n\tcontent: '+';\n}\n#oil-flow-values span[data-item-display=\"oilOut\"]::before\n{\n\tcontent: '-';\n}\n\t\t");
- // make room for oil cell on small devices
- var oilFlowValues = document.getElementById('oil-flow-values');
- var oilFlowCell = oilFlowValues.parentElement;
- oilFlowCell.style.width = '30%';
- }
- function tweakSelection()
- {
- addTweakStyle('no-select', "\ntable.tab-bar,\nspan.item-box,\ndiv.farming-patch,\ndiv.farming-patch-locked,\ndiv#tab-sub-container-combat > span,\ntable.top-links a,\n#hero-area > div:last-child\n{\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n}\n\t\t");
- }
- // tweak stardust monitor of DH2QoL to keep it in place
- function tweakStardust()
- {
- addTweakStyle('dh2qol', "\n#dh2qol-stardustMonitor\n{\n\tdisplay: inline-block;\n\tmargin-left: .25rem;\n\ttext-align: left;\n\twidth: 2.5rem;\n}\n\t\t");
- }
- function tweakSkillLevelText()
- {
- addTweakStyle('', "\ndiv.skill-xp-label\n{\n\ttext-shadow: white 0px 0px 0.5rem;\n}\n\t\t");
- }
- function tweakFightDialog()
- {
- addTweakStyle('smaller-fight-dialog', "\n#dialogue-fight img[width=\"300px\"]\n{\n\twidth: 120px;\n\theight: 50px;\n}\n#dialogue-fight img[src=\"images/icons/combat.png\"] ~ br\n{\n\tdisplay: none;\n}\n\t\t");
- }
- function addAdditionalSkillBars()
- {
- var _loadSkillTabs = window.loadSkillTabs;
- window.loadSkillTabs = function ()
- {
- _loadSkillTabs();
- for (var _i = 0, SKILL_LIST_1 = SKILL_LIST; _i < SKILL_LIST_1.length; _i++)
- {
- var skill = SKILL_LIST_1[_i];
- var unlocked = getGameValue(skill + 'Unlocked') == 1;
- if (!unlocked)
- {
- continue;
- }
- var xp = getGameValue(skill + 'Xp');
- var currentLevelXp = window.getXpNeeded(window.getLevel(xp));
- var nextLevelXp = window.getXpNeeded(window.getLevel(xp) + 1);
- var perc = (xp - currentLevelXp) / (nextLevelXp - currentLevelXp) * 100;
- var progress = document.getElementById('skill-progress-' + skill);
- if (progress)
- {
- progress.style.width = perc + '%';
- }
- }
- };
- // init additional skill bars
- addStyle("\ntd[id^=\"top-bar-level-td-\"]\n{\n\tposition: relative;\n}\n#top-bar-levels .skill-bar\n{\n\tbackground-color: grey;\n\theight: 5px;\n\tposition: absolute;\n\tbottom: 5px;\n\tleft: 60px;\n\tright: 10px;\n}\n#top-bar-levels .skill-bar > .skill-progress\n{\n\tbackground-color: rgb(51, 204, 51);\n\theight: 100%;\n\twidth: 0%;\n}\n\t\t");
- for (var _i = 0, SKILL_LIST_2 = SKILL_LIST; _i < SKILL_LIST_2.length; _i++)
- {
- var skill = SKILL_LIST_2[_i];
- var cell = document.getElementById('top-bar-level-td-' + skill);
- if (!cell)
- {
- continue;
- }
- var levelBar = document.createElement('div');
- levelBar.className = 'skill-bar';
- var progress = document.createElement('div');
- progress.id = 'skill-progress-' + skill;
- progress.className = 'skill-progress';
- levelBar.appendChild(progress);
- cell.appendChild(levelBar);
- // update skill level progress bars on click
- levelBar.addEventListener('click', function ()
- {
- return window.loadSkillTabs();
- });
- }
- window.loadSkillTabs();
- }
- // highlight cooking level requirement when not matched
- function highlightCookinglevel()
- {
- var _cookFoodDialogue = window.cookFoodDialogue;
- window.cookFoodDialogue = function (rawFood)
- {
- _cookFoodDialogue(rawFood);
- var dialog = document.getElementById('dialogue-id-cook-food');
- if (!dialog)
- {
- return;
- }
- var levelReq = document.getElementById('dialogue-cook-levelReq');
- var levelReqLabel = levelReq && levelReq.previousElementSibling;
- if (!levelReq || !levelReqLabel)
- {
- return;
- }
- var fulfilled = window.getCookingLevelReq(rawFood) > window.getLevel(window.cookingXp);
- levelReq.style.color = fulfilled ? 'rgb(204, 0, 0)' : '';
- levelReq.style.fontWeight = fulfilled ? 'bold' : '';
- levelReqLabel.style.color = fulfilled ? 'rgb(204, 0, 0)' : '';
- };
- }
- function amountStyle()
- {
- var tweakName = 'amount-symbol';
- addTweakStyle(tweakName, "\n.item-box:not(#item-box-special-case-questsUnlocked):not(#item-box-pirate):not(#item-box-miner):not(#item-box-boundPumpjacks):not([onclick^=\"openMachineryDialogue(\"]):not(#item-box-sandCollectorsQuest):not(#item-box-boundFilledBonemealBin) > span[data-item-display]::before\n{\n\tcontent: '\\0D7';\n\tmargin-right: .25rem;\n\tmargin-left: -.5rem;\n}\n\t\t");
- function setAmountSymbolVisibility(init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var show = settings.get(settings.KEY.amountSymbol);
- document.body.classList[show ? 'add' : 'remove'](tweakName);
- if (init)
- {
- settings.observe(settings.KEY.amountSymbol, function ()
- {
- return setAmountSymbolVisibility();
- });
- }
- }
- setAmountSymbolVisibility(true);
- }
- function init()
- {
- tweakOil();
- tweakSelection();
- tweakStardust();
- tweakSkillLevelText();
- tweakFightDialog();
- addAdditionalSkillBars();
- highlightCookinglevel();
- amountStyle();
- }
- styleTweaks.init = init;
- })(styleTweaks || (styleTweaks = {}));
- /**
- * add ingame notification boxes
- */
- var notifBoxes;
- (function (notifBoxes)
- {
- notifBoxes.name = 'notifBoxes';
- function addNotifBox(imageKey, itemKey, showFront)
- {
- if (itemKey === void 0)
- {
- itemKey = null;
- }
- if (showFront === void 0)
- {
- showFront = false;
- }
- var notifBox = document.createElement('span');
- notifBox.className = 'notif-box';
- notifBox.id = 'notif-' + imageKey;
- notifBox.style.display = 'none';
- if (showFront)
- {
- notifBox.style.cssFloat = 'left';
- }
- notifBox.innerHTML = "<img src=\"images/" + imageKey + ".png\" class=\"image-icon-50\" id=\"notif-" + imageKey + "-img\">";
- if (itemKey != null)
- {
- notifBox.innerHTML += "<span data-item-display=\"" + itemKey + "\" style=\"margin-left: 10px;\"></span>";
- }
- var notifArea = document.getElementById('notifaction-area');
- if (notifArea)
- {
- notifArea.appendChild(notifBox);
- }
- return notifBox;
- }
- function addTreasureMap()
- {
- var notifBox = addNotifBox('treasureMap', null, true);
- notifBox.setAttribute('onclick', 'openTab("items")');
- function setVisibility()
- {
- var show = window.treasureMap > 0;
- notifBox.style.display = show ? '' : 'none';
- }
- setVisibility();
- observer.add('treasureMap', function ()
- {
- return setVisibility();
- });
- }
- function addWorker()
- {
- var notifBox = addNotifBox('workers', null, true);
- function setVisibility()
- {
- var show = window.workersTimer === 1;
- notifBox.style.display = show ? '' : 'none';
- }
- setVisibility();
- observer.add('workersTimer', function ()
- {
- return setVisibility();
- });
- }
- function init()
- {
- addTreasureMap();
- addWorker();
- }
- notifBoxes.init = init;
- })(notifBoxes || (notifBoxes = {}));
- /**
- * extend market
- */
- var market;
- (function (market)
- {
- market.name = 'market';
- var detectedTedsUIOnce = false;
- function detectTedsUI()
- {
- return detectedTedsUIOnce = detectedTedsUIOnce || typeof window.changeSetting === 'function';
- }
- function showOfferCancelCooldown()
- {
- if (detectTedsUI())
- {
- return;
- }
- addStyle("\n.market-slot-cancel:not([data-cooldown=\"0\"])\n{\n\tbackground: linear-gradient(hsla(12, 40%, 50%, 1), hsla(12, 40%, 40%, 1));\n\tcursor: not-allowed;\n\tposition: relative;\n}\n.market-slot-cancel:not([data-cooldown=\"0\"]):hover\n{\n\tbackground-color: hsla(0, 40%, 50%, 1);\n}\n.market-slot-cancel:not([data-cooldown=\"0\"])::after\n{\n\tcontent: attr(data-cooldown);\n\tposition: absolute;\n\tright: 10px;\n}\n\t\t");
- function slotCooldown(i, init)
- {
- if (init === void 0)
- {
- init = false;
- }
- var cooldownKey = 'marketCancelCooldownSlot' + i;
- var btn = document.getElementById('market-slot-' + i + '-cancel-btn');
- if (btn)
- {
- btn.dataset.cooldown = detectTedsUI() ? '0' : getGameValue(cooldownKey).toString();
- }
- if (init)
- {
- observer.add(cooldownKey, function ()
- {
- return slotCooldown(i);
- });
- }
- }
- for (var i = 1; i <= 3; i++)
- {
- slotCooldown(i, true);
- }
- }
- function init()
- {
- showOfferCancelCooldown();
- }
- market.init = init;
- })(market || (market = {}));
- /**
- * init
- */
- var scriptInitialized = false;
- function init()
- {
- console.info('[%s] "DH2 Fixed %s" up and running.', (new Date).toLocaleTimeString(), version);
- scriptInitialized = true;
- var initModules = [
- settings
- , notifications
- , log
- , gameEvents
- , temporaryFixes
- , crafting
- , itemBoxes
- , chat
- , timer
- , smelting
- , fishingInfo
- , recipeTooltips
- , fixNumbers
- , machineDialog
- , amountInputs
- , newTopbar
- , styleTweaks
- , notifBoxes
- , market
- ];
- window.initModules = initModules;
- for (var _i = 0, initModules_1 = initModules; _i < initModules_1.length; _i++)
- {
- var module = initModules_1[_i];
- try
- {
- module.init();
- }
- catch (error)
- {
- console.error('Error during initialization in module "' + module.name + '":', error);
- }
- }
- }
- document.addEventListener('DOMContentLoaded', function ()
- {
- var oldValues = new Map();
- var _doCommand = window.doCommand;
- window.doCommand = function (data)
- {
- if (data.startsWith('REFRESH_ITEMS='))
- {
- oldValues = new Map();
- for (var _i = 0, _a = window.jsItemArray; _i < _a.length; _i++)
- {
- var key = _a[_i];
- oldValues.set(key, getGameValue(key));
- }
- _doCommand(data);
- if (!scriptInitialized)
- {
- init();
- }
- return;
- }
- else if (!scriptInitialized)
- {
- if (data.startsWith('CHAT='))
- {
- var parts = data.substr(5).split('~');
- return chat.newAddToChatBox(parts[0], parts[1], parts[2], parts[3], 0);
- }
- else if (data.startsWith('PM='))
- {
- return chat.newAddToChatBox(window.username, '0', '0', data.substr(3), 1);
- }
- }
- var ret = commands.process(data);
- if (ret === void 0)
- {
- ret = _doCommand(commands.formatData(data));
- }
- return ret;
- };
- var _refreshItemValues = window.refreshItemValues;
- window.refreshItemValues = function (itemKeyList, firstLoad)
- {
- _refreshItemValues(itemKeyList, firstLoad);
- for (var _i = 0, itemKeyList_1 = itemKeyList; _i < itemKeyList_1.length; _i++)
- {
- var key = itemKeyList_1[_i];
- observer.notify(key, oldValues.get(key));
- }
- };
- });
- /**
- * fix web socket errors
- */
- var main;
- (function (main)
- {
- var WS_TIMEOUT_SEC = 30;
- var WS_TIMEOUT_CODE = 3000;
- var WS_OPEN_TIMEOUT_SEC = 2 * 60; // 2 minutes
- // reload the page after 5 consecutive reconnect attempts without successfully opening the websocket once
- var MAX_RECONNECTS = 5;
- function webSocketLoaded(event)
- {
- if (window.webSocket == null)
- {
- console.error('WebSocket instance not initialized!');
- return;
- }
- // cache old event listener
- var _onClose = window.webSocket.onclose;
- var _onError = window.webSocket.onerror;
- var _onMessage = window.webSocket.onmessage;
- var _onOpen = window.webSocket.onopen;
- var commandQueue = [];
- var _cBytes = window.cBytes;
- window.cBytes = function (command)
- {
- if (window.webSocket && window.webSocket.readyState === WebSocket.OPEN)
- {
- _cBytes(command);
- }
- else
- {
- commandQueue.push(command);
- }
- };
- var pageLoaded = false;
- var wsTimeout = null;
- var reconnectAttempts = 0;
- function onTimeout()
- {
- wsTimeout = null;
- // renew the websocket
- if (reconnectAttempts <= MAX_RECONNECTS)
- {
- window.webSocket = new WebSocket(window.SSL_ENABLED);
- window.ignoreBytesTracker = Date.now();
- initWSListener(window.webSocket);
- reconnectAttempts++;
- }
- if (window.webSocket)
- {
- window.webSocket.close(WS_TIMEOUT_CODE, 'Connection timed out after ' + WS_TIMEOUT_SEC + ' seconds');
- }
- }
- function updateWSTimeout()
- {
- if (wsTimeout)
- {
- window.clearTimeout(wsTimeout);
- }
- wsTimeout = window.setTimeout(onTimeout, WS_TIMEOUT_SEC * 1e3);
- }
- var messageQueue = [];
- function onMessage(event)
- {
- if (pageLoaded)
- {
- updateWSTimeout();
- return _onMessage.call(this, event);
- }
- else
- {
- messageQueue.push(event);
- }
- };
- var wsOpenTimeout = null;
- function onOpenTimeout()
- {
- wsOpenTimeout = null;
- location.reload();
- }
- function onOpen(event)
- {
- reconnectAttempts = 0;
- if (wsOpenTimeout)
- {
- window.clearTimeout(wsOpenTimeout);
- wsOpenTimeout = null;
- }
- // do the handshake first
- _onOpen.call(this, event);
- commandQueue.forEach(function (command)
- {
- return window.cBytes(command);
- });
- }
- function onError(event)
- {
- console.error('error in websocket:', event);
- return _onError.call(this, event);
- }
- function onClose(event)
- {
- console.info('websocket closed:', event);
- if (event.code !== WS_TIMEOUT_CODE || reconnectAttempts > MAX_RECONNECTS)
- {
- location.reload();
- }
- return _onClose.call(this, event);
- }
- function initWSListener(ws)
- {
- if (ws.readyState === WebSocket.CONNECTING)
- {
- wsOpenTimeout = window.setTimeout(onOpenTimeout, WS_OPEN_TIMEOUT_SEC * 1e3);
- }
- ws.onclose = onClose;
- ws.onerror = onError;
- ws.onmessage = onMessage;
- ws.onopen = onOpen;
- }
- initWSListener(window.webSocket);
- document.addEventListener('DOMContentLoaded', function ()
- {
- pageLoaded = true;
- messageQueue.forEach(function (event)
- {
- return window.webSocket.onmessage(event);
- });
- });
- }
- function isScriptElement(el)
- {
- return el.nodeName === 'SCRIPT';
- }
- function isWebSocketScript(script)
- {
- return script.src.includes('socket.js');
- }
- var found = false;
- var scripts = document.head ? document.head.querySelectorAll('script') : [];
- for (var i = 0; i < scripts.length; i++)
- {
- if (isWebSocketScript(scripts[i]))
- {
- // does this work?
- scripts[i].onload = webSocketLoaded;
- found = true;
- }
- }
- if (!found)
- {
- // create an observer instance
- var mutationObserver_1 = new MutationObserver(function (mutationList)
- {
- mutationList.forEach(function (mutation)
- {
- if (mutation.addedNodes.length === 0)
- {
- return;
- }
- for (var i = 0; i < mutation.addedNodes.length; i++)
- {
- var node = mutation.addedNodes[i];
- if (isScriptElement(node) && isWebSocketScript(node))
- {
- mutationObserver_1.disconnect();
- node.onload = webSocketLoaded;
- return;
- }
- }
- });
- });
- mutationObserver_1.observe(document.head
- , {
- childList: true
- });
- }
- // fix scrollText (e.g. when joining the game and receiving xp at that moment)
- window.mouseX = window.innerWidth / 2;
- window.mouseY = window.innerHeight / 2;
- })(main || (main = {}));
- })();