DHO Fixed

Improve Diamond Hunt Online (fixes some inconsistencies)

当前为 2017-01-02 提交的版本,查看 最新版本

// ==UserScript==
// @name         DHO Fixed
// @namespace    FileFace
// @description  Improve Diamond Hunt Online (fixes some inconsistencies)
// @version      0.14.1
// @author       Zorbing
// @grant        none
// @run-at       document-start
// @include      http://www.diamondhunt.co/game.php
// ==/UserScript==

(function ()
{
'use strict';

let observedKeys = new Map();
/**
 * Observes the given key for change
 * 
 * @param {string} key	The name of the variable
 * @param {Function} fn	The function which is called on change
 */
function observe(key, fn)
{
	if (!observedKeys.has(key))
	{
		observedKeys.set(key, []);
	}
	observedKeys.get(key).push(fn);
}
function initObservable()
{
	const oldLoadGlobals = window.loadGlobals;
	window.loadGlobals = (key, newValue) =>
	{
		if (key === undefined)
		{
			return;
		}

		const oldValue = window[key];
		const ret = oldLoadGlobals(key, newValue);
		if (oldValue !== newValue)
		{
			(observedKeys.get(key) || []).forEach(fn => fn(key, oldValue, newValue));
		}
		return ret;
	};
}



const settings = {
	reorderFarming: {
		title: 'Set seed orders coherent'
		, defaultValue: true
	}
	, unifyMachineryDialog: {
		title: 'Unify the machinery dialog (for sand collector)'
		, defaultValue: true
	}
	, hideUnnecessaryPrice: {
		title: 'Hide unnecessary prices'
		, defaultValue: true
	}
	, useFastLevelCalculation: {
		title: 'Use fast level calculation'
		, defaultValue: true
	}
	, hideSomeCraftRecipes: {
		title: 'Hide some crafting recipes'
		, defaultValue: true
	}
};
function getSetting(key)
{
	if (!settings.hasOwnProperty(key))
	{
		return;
	}
	const name = 'setting.' + key;
	return localStorage.hasOwnProperty(name) ? JSON.parse(localStorage.getItem(name)) : settings[key].defaultValue;
}
function setSetting(key, value)
{
	if (!settings.hasOwnProperty(key))
	{
		return;
	}
	localStorage.setItem('setting.' + key, JSON.stringify(value));
}
function initSettings()
{
	const table = document.getElementById('settings-tab').querySelector('table');
	if (!table)
	{
		return;
	}
	const headerRow = table.insertRow(-1);
	headerRow.innerHTML = `<th style="background-color:black;color:orange">Userscript "DHO Fixed" (requires reload)</th>`;

	for (let key in settings)
	{
		let value = getSetting(key);
		const row = table.insertRow(-1);
		row.innerHTML = `<td id="fake-link-top">
			${settings[key].title}: <span style="color:cyan;" id="userscript-${key}">${value ? 'on' : 'off'}</span>
		</td>`;
		const indicator = document.getElementById('userscript-' + key);;
		row.addEventListener('click', () =>
		{
			value = !value;
			setSetting(key, value);
			indicator.textContent = value ? 'on' : 'off';
		});
	}

	const settingLink = document.querySelector('.top-menu td[onclick^="openTab"]');
	settingLink.addEventListener('click', function ()
	{
		const activeTab = document.querySelector('#tab-tr td[style^="background: linear-gradient(rgb"]');
		if (activeTab)
		{
			activeTab.style.background = 'linear-gradient(black, grey)';
		}
	});
}



function fixKeyItems()
{
    // remove unnecessary br element
    const oilPump = document.getElementById('key-item-handheldOilPump-box');
    let br = oilPump && oilPump.nextElementSibling;
    if (!br)
    {
        br = document.createElement('br');
    }

    // add br element after img in oil pipe element
    const oilPipe = document.getElementById('key-item-bindedOilPipe-box');
    let img = oilPipe && oilPipe.children[0];
    img = img && img.children[0];
    img.parentNode.insertBefore(br, img.nextSibling);
}



const seedOrder = ['bloodLeafSeeds', 'dottedGreenLeafSeeds', 'redMushroomSeeds', 'potatoSeeds', 'greenLeafSeeds', 'strawberrySeeds', 'redMushroomTreeSeeds', 'blewitMushroomSeeds', 'wheatSeeds', 'starDustSeeds', 'blewitMushroomTreeSeeds', 'snapeGrassSeeds', 'limeLeafSeeds', 'appleTreeSeeds', 'iceBerrySeeds', 'goldLeafSeeds', 'starDustTreeSeeds', 'stripedLeafSeeds', 'essenceSeeds', 'crystalLeafSeeds', 'megaDottedGreenLeafSeeds', 'megaRedMushroomSeeds', 'megaGreenLeafSeeds', 'essenceTreeSeeds', 'megaBlewitMushroomSeeds', 'megaLimeLeafSeeds', 'stripedCrystalLeafSeeds'];
const seedTitle = {
	potatoSeeds: 'Potato Seeds'
	, strawberrySeeds: 'Strawberry Seeds'
	, wheatSeeds: 'Wheat Seeds'
	, dottedGreenLeafSeeds: 'Dotted Green Leaf Seeds'
	, greenLeafSeeds: 'Green Leaf Seeds'
	, limeLeafSeeds: 'Lime Leaf Seeds'
	, goldLeafSeeds: 'Gold Leaf Seeds'
	, stripedLeafSeeds: 'Striped Leaf Seeds'
	, crystalLeafSeeds: 'Crystal Leaf Seeds'
	, redMushroomSeeds: 'Red Mushroom Seeds'
	, blewitMushroomSeeds: 'Blewit Mushroom Seeds'
	, appleTreeSeeds: 'Apple Tree Seeds'
	, snapeGrassSeeds: 'Snape Grass Seeds'
	, redMushroomTreeSeeds: 'Red Mushroom Tree Seeds'
	, blewitMushroomTreeSeeds: 'Blewit Mushroom Tree Seeds'
	, starDustSeeds: 'Star Dust Seeds'
};
function fixFarming()
{
    const inputs = document.querySelectorAll('#dialog-planter input[type="image"]');
    for (let i = inputs.length-1; i >= 0; i--)
    {
        const input = inputs[i];
        const key = input.id.replace('planter-input-img-', '');
        input.title = seedTitle[key];
    }

	if (!getSetting('reorderFarming'))
	{
		return;
	}

	let planterEl = inputs[0];
	const planterParent = planterEl.parentNode;
	let boxEl = document.querySelector('#farming-tab .inventory-item-box-farming').parentNode;
	const boxParent = boxEl.parentNode;
	for (let i = seedOrder.length-1; i >= 0; i--)
	{
		const key = seedOrder[i];
		const input = document.getElementById('planter-input-img-' + key);
		if (input)
		{
			planterParent.insertBefore(input, planterEl);
			planterParent.insertBefore(document.createTextNode(' '), planterEl);
			planterEl = input;
		}
		const box = document.getElementById('item-' + key + '-box');
		if (box)
		{
			boxParent.insertBefore(box.parentNode, boxEl);
			boxParent.insertBefore(document.createTextNode(' '), boxEl);
			boxEl = box.parentNode;
		}
	}
}



function fixServerMsg()
{
	const serverMsgEl = document.querySelector('#server-inner-msg');
	if (!serverMsgEl)
	{
		return;
	}

	const serverMsg = serverMsgEl.textContent;
	const close = document.querySelector('#server-top-msg > *:last-child');
	if (localStorage.getItem('closedServerMsg') == serverMsg)
	{
		close.click();
		return;
	}

	close.addEventListener('click', function ()
	{
		localStorage.setItem('closedServerMsg', serverMsg);
	});
}



const bgColor = 'hsla(0, 100%, 90%, 1)';
const imgSrc2Key = {
	'bronzebar': 'bronzeBar'
	, 'ironbar': 'ironBar'
	, 'silverbar': 'silverBar'
	, 'goldbar': 'goldBar'
	, 'stonefurnace': 'stoneFurnace'
	, 'bronzefurnace': 'bronzeFurnace'
	, 'ironfurnace': 'ironFurnace'
	, 'silverfurnace': 'silverFurnace'
	, 'goldfurnace': 'goldFurnace'
	, 'pic_coin': 'coins'
	, 'stardust': 'starDust'
	, 'treasureKey': 'treasureChestKey'
	, 'dottedgreenleaf': 'dottedGreenLeaf'
	, 'redmushroom': 'redMushroom'
	, 'greenleaf': 'greenLeaf'
	, 'limeleaf': 'limeLeaf'
	, 'blewitmushroom': 'blewitMushroom'
	, 'goldleaf': 'goldLeaf'
	, 'pureWater': 'pureWaterPotion'
	, 'snapegrass': 'snapeGrass'
	, 'crystalleaf': 'crystalLeaf'
	, 'starDustConverter': 'starGemPotion'
	, 'superStargemPotion': 'superStarGemPotion'
	, 'superoilpotion': 'superOilPotion'
};
const furnaceLevels = ['', 'stone', 'bronze', 'iron', 'silver', 'gold', 'ancient', 'promethium'];
function checkRequirements(row, xpKey, init = true)
{
	const isRed = row.style.backgroundColor == 'rgb(255, 128, 128)';
	let everythingFulfilled = true;
	let keys2Observe = [];

	const levelEl = row.cells[2];
	const levelHighEnough = parseInt(levelEl.textContent, 10) <= window.getLevel(window[xpKey]);
	levelEl.style.color = levelHighEnough ? '' : 'red';
	everythingFulfilled = everythingFulfilled && levelHighEnough;
	keys2Observe.push(xpKey);

	const reqEl = row.cells[3];
	const children = reqEl.children;
	// check for each requirement if it is fulfilled
	for (let i = 0; i < children.length; i++)
	{
		const el = children[i];
		if (el.tagName != 'IMG')
		{
			continue;
		}
		let key = el.src.replace(/^.+images\/.*?([^\/]+)\..+$/, '$1');
		key = imgSrc2Key[key] || key;
		// wrap the amount with a span element
		let valueSpan = el.nextSibling;
		if (valueSpan.nodeType == Node.TEXT_NODE)
		{
			const valueTextNode = valueSpan;
			valueSpan = document.createElement('span');
			valueTextNode.parentNode.insertBefore(valueSpan, valueTextNode);
			valueSpan.appendChild(valueTextNode);
		}

		const amount = parseInt(valueSpan.textContent
			.replace(/M/i, '000000')
			.replace(/B/i, '000000000')
			.replace(/\D/g, ''), 10)
		;
		const has = parseInt(window[key] || '0', 10);
		let fulfilled = has >= amount;
		if (key == 'watering-can')
		{
			fulfilled = window.getLevel(window.merchantingXp) >= amount;
			keys2Observe.push('merchantingXp');
		}
		else if (key == 'gem')
		{
			fulfilled = window.sapphire >= amount || window.emerald >= amount || window.ruby >= amount || window.diamond >= amount;
			keys2Observe.push(...['sapphire', 'emerald', 'ruby', 'diamond']);
		}
		else if (key == 'wooden_slave')
		{
			fulfilled = parseInt(window.miners, 10) >= amount;
			keys2Observe.push('miners');
		}
		else if (/furnace/i.test(key))
		{
			const furnaceLevel = furnaceLevels.indexOf(key.replace(/furnace/i, ''));
			fulfilled = fulfilled || parseInt(window.bindedFurnaceLevel, 10) >= furnaceLevel;
			keys2Observe.push(...[key, 'bindedFurnaceLevel']);
		}
		else
		{
			keys2Observe.push(key);
		}
		valueSpan.style.color = fulfilled ? '' : 'red';
		everythingFulfilled = everythingFulfilled && fulfilled;
	}
	levelEl.style.backgroundColor = everythingFulfilled ? '' : bgColor;
	reqEl.style.backgroundColor = everythingFulfilled ? '' : bgColor;

	if (init)
	{
		for (let key of keys2Observe)
		{
			observe(key, (key, oldValue, newValue) => checkRequirements(row, xpKey, false));
		}
	}
}

function highlightRequirements()
{
	const craftTable = document.querySelector('#enchanted-hammer-boxes + table');
	const craftingRows = craftTable.rows;
	for (let i = 2; i < craftingRows.length; i++)
	{
		const row = craftingRows[i];
		checkRequirements(row, 'craftingXp');
	}

	const brewingTable = document.querySelector('#brewing-tab table');
	const brewingRows = brewingTable.rows;
	for (let i = 2; i < brewingRows.length; i++)
	{
		const row = brewingRows[i];
		checkRequirements(row, 'brewingXp');
	}
}



function fixMarket()
{
	// create an observer instance
	const observer = new MutationObserver(function(mutations)
	{
		mutations.forEach(function(mutation)
		{
			// fix icons
			var dragonFurnace = mutation.target.querySelector('input[alt="dragonFurnace"]');
			if (dragonFurnace)
			{
				dragonFurnace.src = dragonFurnace.src.replace(/\.png$/, '.gif');
			}

			// hide duplicate orb
			var orbs = mutation.target.querySelectorAll('input[alt="upgradeEnchantedRake"]');
			if (orbs.length > 1)
			{
				orbs[1].style.display = 'none';
			}
		});
	});
	// configuration of the observer:
	const config = {
		childList: true
	};

	const table = document.getElementById('selling-tradable-table');
	observer.observe(table, config);

	// fix loading icons
	const loadingImgs = document.querySelectorAll('[src="images/loading_statique.png"]');
	for (var i = 0; i < loadingImgs.length; i++)
	{
		loadingImgs[i].src = 'images/loading.gif';
	}

	const oldFilterBuyables = window.filterBuyables;
	let lastFilterText = null;
	window.filterBuyables = (text) =>
	{
		lastFilterText = text;
		return oldFilterBuyables(text);
	};
	const oldApplyToBuyingTable = window.applyToBuyingTable;
	window.applyToBuyingTable = (...args) =>
	{
		const ret = oldApplyToBuyingTable(...args);
		if (lastFilterText != null)
		{
			window.filterBuyables(lastFilterText);
		}
		return ret;
	};
}



const maxLevel = 100;
const maxLevelVirtual = 1000;
let levelXp = new Array(maxLevelVirtual+1);
function calcLevelXp(level)
{
	return level > 0 ? Math.round(Math.pow((level-1), 3 + ((level-1) / 200))) : 0;
}
function getLevelXp(level)
{
	return levelXp[level-1] || calcLevelXp(level);
}
const getDynamicLevel = (function ()
{
	const size = Math.pow(2, Math.ceil(Math.log2(maxLevel)));
	let xpTree = new Array(size);
	let levelTree = new Array(size);
	const sizeVirtual = Math.pow(2, Math.ceil(Math.log2(maxLevelVirtual)));
	let xpTreeVirtual = new Array(sizeVirtual);
	let levelTreeVirtual = new Array(sizeVirtual);
	createNode(xpTree, levelTree, 1, maxLevel, 0);
	createNode(xpTreeVirtual, levelTreeVirtual, 1, maxLevelVirtual, 0);

	function createNode(xpArray, levelArray, start, end, i)
	{
		const current = start + Math.pow(2, Math.floor(Math.log2(end - start + 1))) - 1;
		xpArray[i] = getLevelXp(current);
		levelArray[i] = current;

		if (current - start > 0)
		{
			createNode(xpArray, levelArray, start, current-1, 2*i + 1);
		}
		if (end - current > 0)
		{
			createNode(xpArray, levelArray, current+1, end, 2*i + 2);
		}
	}

	function getDynamicLevel(playerXP, useVirtual = false)
	{
		const isVirtual = window.virtualLevelsOn !== 0 && useVirtual === true;
		const xpArray = isVirtual ? xpTreeVirtual : xpTree;
		const levelArray = isVirtual ? levelTreeVirtual : levelTree;
		let i = 0;
		let level = 0;
		while (xpArray[i] != null)
		{
			if (playerXP == xpArray[i])
			{
				return levelArray[i];
			}
			else if (playerXP < xpArray[i])
			{
				i = 2*i+1;
			}
			else if (playerXP > xpArray[i])
			{
				level = levelArray[i];
				i = 2*i+2;
			}
		}
		return level;
	}

	return getDynamicLevel;
})();
function getLevel(playerXP)
{
	return getDynamicLevel(playerXP, false);
}
function getVirtualLevel(playerXP)
{
	return getDynamicLevel(playerXP, true);
}

function getGlobalLevel()
{
	return getDynamicGlobalLevel(false);
}
function getDynamicGlobalLevel(useVirtual = false)
{
	return Math.floor(getDynamicLevel(parseInt(window.miningXp, 10), useVirtual))
		+ Math.floor(getDynamicLevel(parseInt(window.craftingXp, 10), useVirtual))
		+ Math.floor(getDynamicLevel(parseInt(window.brewingXp, 10), useVirtual))
		+ Math.floor(getDynamicLevel(parseInt(window.merchantingXp, 10), useVirtual))
		+ Math.floor(getDynamicLevel(parseInt(window.exploringXp, 10), useVirtual))
		+ Math.floor(getDynamicLevel(parseInt(window.cookingXp, 10), useVirtual))
		+ Math.floor(getDynamicLevel(parseInt(window.magicXp, 10), useVirtual))
	;
}
function improveLevelCalculation()
{
	if (!getSetting('useFastLevelCalculation'))
	{
		return;
	}

	for (var i = 1; i < maxLevelVirtual; i++)
	{
		levelXp[i-1] = calcLevelXp(i);
	}
	window.getLevel = getLevel;
	window.getVirtualLevel = getVirtualLevel;
	window.getGlobalLevel = getGlobalLevel;
}



function fixInventory()
{
	if (!getSetting('hideUnnecessaryPrice'))
	{
		return;
	}

	const tab = document.getElementById('gatherings-tab');
	const coinImgs = tab.querySelectorAll('span[id^="item-"][id$="-box"] img[src="images/pic_coin.png"]');
	for (let i = 0; i < coinImgs.length; i++)
	{
		const coinImg = coinImgs[i];
		const price = coinImg.nextSibling;
		if (price.nodeType == Node.TEXT_NODE && !/\d/.test(price.textContent))
		{
			const parent = coinImg.parentNode;
			parent.removeChild(coinImg);
			parent.removeChild(price);
		}
	}
}



const oilConsumption = {
	'drill': 1
	, 'crusher': 15
	, 'giantDrill': 30
	, 'roadHeader': 50
	, 'bucketWheelExcavator': 150
	, 'giantBWE': 500
	, 'sandCollector': 5
};
function getOilValueFromMachine(machinery)
{
	return (oilConsumption[machinery] || 0) * window['binded' + machinery[0].toUpperCase() + machinery.substr(1)];
}
function openOilDialogue(varname)
{
	const gearOnPath = 'images/spinning-gear.gif';
	const gearOffPath = 'images/spinning-gear-off.gif';
	const oilArea = document.getElementById('oilUsage-area');
	const oilValue = document.getElementById('oilUsage-value');
	const repairArea = document.getElementById('machinery-repair-area');

	let machine = varname.replace(/key-item-binded([^-]+)-box/, '$1');
	machine = machine[0].toLowerCase() + machine.substr(1);

	// PROGRESS BAR
	var hasRepair = window.bindedPromethiumWrench > 0;
	if (machine == 'sandCollector')
	{
		// hide repair part (ensure, it is hidden)
		repairArea.setAttribute('style', 'padding: 0; width: 0px; height: 0px; overflow: hidden; border: 0;');
	}
	else
	{
		// show repair part if available
		repairArea.setAttribute('style', 'display: ' + (hasRepair ? 'block' : 'none') + ';');

		const progressBar = document.getElementById('progress-bar-repair-opened');
		const percent = window[machine + 'Repair'];
		const bgColor = percent < 20 ? 'yellow' : (percent >= 50 ? 'lime' : 'yellow');
		progressBar.style.backgroundColor = bgColor;
		progressBar.style.width = percent + '%';
	}
	// END PROGRESS BAR

	oilValue.innerHTML = window.getOilValueFromMachine(machine);
	document.getElementById('machineryChosenPopup').value = machine;
	const isOn = window[machine + 'AreOn'] == 1;
	document.getElementById('myonoffswitch').checked = isOn;
	document.getElementById('myonoffswitch-gear').src = isOn ? gearOnPath : gearOffPath;
	oilArea.style.display = isOn ? '' : 'none';

	window.$('#machinery-dialog').dialog(
	{
		width: 400
	});
}
function fixMachinery()
{
	const oldChangeSmeltingValue = window.changeSmeltingValue;
	window.changeSmeltingValue = () =>
	{
		window.setSmeltingBarAgain(
			window.barTypeSelectedToSmeltGlobal
			, document.getElementById('smeltingAmountRequested')
		);
	};

	if (!getSetting('unifyMachineryDialog'))
	{
		return;
	}

	window.getOilValueFromMachine = getOilValueFromMachine;
	window.openOilDialogue = openOilDialogue;
}



const potionRequirements = {
	'seedPotion': {
		level: 5
		, dottedGreenLeaf: 5
		, redMushroom: 100
		, greenLeaf: 1
	}
};
let oldCanBrewItem;
function canBrewItem(command)
{
	var requirements = potionRequirements[command];
	if (!requirements)
	{
		return oldCanBrewItem(command);
	}

	for (var key in requirements)
	{
		if (key == 'level')
		{
			if (getLevel(brewingXp) < requirements.level)
			{
				return false;
			}
		}
		else if (window[key] < requirements[key])
		{
			return false;
		}
	}
	return true;
}
function fixBrewing()
{
	oldCanBrewItem = window.canBrewItem;
	window.canBrewItem = canBrewItem;
}



const tabs2Fix = {
	repair: {
		name: 'Machinery'
		, url: 'https://www.reddit.com/r/DiamondHunt/wiki/online/tabs/machinery'
	}
	, store: {
		name: 'Market'
		, url: 'https://www.reddit.com/r/DiamondHunt/wiki/online/tabs/market'
	}
	, 'npc-store': {
		name: 'Game Shop'
		, url: 'https://www.reddit.com/r/DiamondHunt/wiki/online/tabs/market/game'
	}
	, 'donor-store': {
		name: 'Donor Shop'
		, url: 'https://www.reddit.com/r/DiamondHunt/wiki/online/tabs/market/donor'
	}
	, 'player-store': {
		name: 'Player Market'
		, url: 'https://www.reddit.com/r/DiamondHunt/wiki/online/tabs/market/player'
	}
	, stats: {
		name: 'Leaderboards'
		, url: 'https://www.reddit.com/r/DiamondHunt/wiki/online/tabs/stats'
	}
	, coop: {
		name: 'Group Tasks'
		, url: 'https://www.reddit.com/r/DiamondHunt/wiki/online/tabs/coop'
	}
	, collectables: {
		name: 'Collectables'
	}
	, miningEngineer: {
		name: 'Mining Engineer'
	}
	, 'ach-explore': {
		name: 'Exploring — Equipment'
		, url: 'https://www.reddit.com/r/DiamondHunt/wiki/online/tabs/exploration#wiki_equipment'
	}
};
function tabTitleLink2Span(title)
{
	const span = title.parentNode;
	span.appendChild(title.firstChild);
	span.removeChild(title);
	span.setAttribute('tooltip', '');
	span.style.color = 'gold';
	span.style.fontSize = '24pt';
}
function fixTabs()
{
	function removeElement(el)
	{
		el.parentNode.removeChild(el);
	}
	/**
	 * some special treatment
	 */

	const achievementTitle = document.querySelector('#ach-tab a');
	tabTitleLink2Span(achievementTitle);

	const npcH1 = document.querySelector('#npc-store-tab h1');
	removeElement(npcH1);

	const vendorBr = document.querySelector('#vendor-tab > br:first-child');
	removeElement(vendorBr);
	const vendorTitle = document.querySelector('#vendor-tab a');
	tabTitleLink2Span(vendorTitle);

	const wizardBr = document.querySelector('#wizard-tab > br:first-child');
	removeElement(wizardBr);

	const achTitle = document.querySelector('#archaeology-tab a');
	achTitle.title = '';
	const achCraftTitle = document.querySelector('#archaeology-crafting-tab a');
	achCraftTitle.textContent = 'Exploring — Crafting'.toUpperCase();
	tabTitleLink2Span(achCraftTitle);
	const cookingTitle = document.querySelector('#cooking-tab a');
	cookingTitle.textContent = 'Exploring — Cooking'.toUpperCase();
	cookingTitle.title = '';
	cookingTitle.parentNode.setAttribute('tooltip', 'Open Wiki');

	const magicSpellbookTitle = document.querySelector('#spellbook-tab a');
	magicSpellbookTitle.textContent = 'Magic — spellbook'.toUpperCase();
	const magicCraftTitle = document.querySelector('#magiccrafting-tab a');
	magicCraftTitle.textContent = 'Magic — Crafting'.toUpperCase();
	tabTitleLink2Span(magicCraftTitle);

	removeElement(document.querySelector('#repair-tab > br:last-child'));
	removeElement(document.querySelector('#repair-tab > br:last-child'));
	removeElement(document.querySelector('#miningEngineer-tab br'));
	removeElement(document.querySelector('#brewing-tab br'));
	removeElement(document.querySelector('#archaeology-tab br'));
	removeElement(document.querySelector('#ach-explore-tab br'));
	removeElement(document.querySelector('#ach-explore-tab br'));
	const archCraftBr = document.querySelector('#archaeology-crafting-tab br');
	archCraftBr.parentNode.insertBefore(document.createElement('br'), archCraftBr);
	removeElement(document.querySelector('#cooking-tab br'));
	removeElement(document.querySelector('#cooking-tab br'));
	removeElement(document.querySelector('#cooking-tab br'));
	removeElement(document.querySelector('#magic-tab br'));
	removeElement(document.querySelector('#magiccrafting-tab br'));
	removeElement(document.querySelector('#magiccrafting-tab br'));
	for (let i = 0; i < 10; i++)
	{
		removeElement(document.querySelector('#magiccrafting-tab > span + br'));
	}
	removeElement(document.querySelector('#store-tab br'));
	removeElement(document.querySelector('#player-store-tab br'));
	removeElement(document.querySelector('#stats-tab br'));
	removeElement(document.querySelector('#stats-tab br'));
	removeElement(document.querySelector('#grouptasks-createorjoin br'));
	removeElement(document.querySelector('#grouptasks-notstarted br'));
	removeElement(document.querySelector('#grouptasks-notstarted br'));
	removeElement(document.querySelector('#grouptasks-started br'));


	for (let key in tabs2Fix)
	{
		const tab = tabs2Fix[key];
		const tabEl = document.getElementById(key + '-tab');
		const tmpEl = document.createElement('tmpWrapper');
		let html = '<center>';
		if (tab.url)
		{
			html += `<span class="activate-tooltip" style="disply:inline-block;" title="Open Wiki">
				<a class="title-link" href="${tab.url}" target="_blank" title="Open Wiki">${tab.name.toUpperCase()}</a>
			</span>`;
		}
		else
		{
			html += `<span class="activate-tooltip" style="disply:inline-block; color: gold; font-size: 24pt;">
				${tab.name.toUpperCase()}
			</span>`;
		}
		html += '</center><br>';
		tmpEl.innerHTML = html;
		let el = tabEl.firstElementChild;
		for (let i = tmpEl.children.length-1; i >= 0; i--)
		{
			const child = tmpEl.children[i];
			tabEl.insertBefore(child, el);
			el = child;
		}
	}
}



const recipes = {
	shovel: 'shovel'
	, promethiumWrench: 'bindedPromethiumWrench'
	, glassBlowingPipe: 'bindedGlassBlowingPipe'
	, oilPipe: 'bindedOilPipe'
	, planter: 'bindedPlanter'
	, trowel: 'bindedTrowel'
	, brewingKit: 'brewingKitBinded'
	, rocket: 'bindedRocket'
	, redPumpJack: 'bindedRedPumpJack'
	, explorersBrush: 'bindedExplorersBrush'
	, oilFactory: 'bindedOilFactory'
	, robot: 'bindedRobot'
	, oilRefinery: 'bindedOilRefinery'
	, superRobot: 'bindedSuperRobot'
};
function hideCraftingRecipes()
{
	if (!getSetting('hideSomeCraftRecipes'))
	{
		return;
	}

	const bindedFurnaceLevel = parseInt(window.bindedFurnaceLevel, 10);
	for (let i = 1; i <= bindedFurnaceLevel; i++)
	{
		const row = document.getElementById('craft-' + furnaceLevels[i] + 'Furnace');
		if (row)
		{
			row.style.display = 'none';
		}
	}

	for (let key in recipes)
	{
		if (window[recipes[key]] != 0)
		{
			document.getElementById('craft-' + key).style.display = 'none';
		}
	}
}



/**
 * init
 */

document.addEventListener('DOMContentLoaded', function ()
{
	initObservable();
	initSettings();

	fixKeyItems();
	fixFarming();
	fixServerMsg();
	highlightRequirements();
	fixMarket();
	improveLevelCalculation();
	fixInventory();
	fixMachinery();
	fixBrewing();
	fixTabs();
	hideCraftingRecipes();
});

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址