UD Barrista - iSpy

Places a menu bar across the top with stats and buttons

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name		    UD Barrista - iSpy
// @author			Bradley Sattem (a.k.a. Aichon)
// @namespace		https://ud.dxavier.net
// @version			1.1.1.4
// @description		Places a menu bar across the top with stats and buttons
// @match			http://urbandead.com/*
// @match			http://www.urbandead.com/*
// @match			https://urbandead.com/*
// @match			https://www.urbandead.com/*
// @grant       	none
// ==/UserScript==

/* Urban Dead Barrista
 *
 * Copyright (C) 2016 Bradley Sattem
 * Last Modified: 2016-07-26
 *
 * Tested under: Chrome 51 on Windows
 *
 * Contact: [my first name [DOT] my last name]@gmail.com (check the Copyright info for my name)
 *
 * Changes:
 *   v1.0.9 - Adding Dumbwit button. Fixing a load of syntax errors.
 *   v1.0.8 - Metadata updates.
 *   v1.0.7 - Feature: Changed stuff so that SatPhone should hopefully work
 *   v1.0.6 - Feature: Added IDs to certain elements so other userscripts could find them easily
 *   v1.0.5 - Bug Fix: Profile pages no longer screwed up
 *   v1.04  - No longer hides Dumbwit timestamps
 *   v1.03-chrome - Fixed some line-height issues observed by a user
 *   v1.0.3 - Bug Fix: Removed development code that could cause issues in non-dev setups
 *   v1.0.2 - Bug Fix: Settings and RG buttons work after saving your settings
 *   v1.0.1 - Settings button now works on more pages
 *   v1.0   - Now works in Firefox
 *          - Gun Stores no longer disappear in Malls
 *          - Fixed to work with game update for safehouses
 *
 * Thanks:
 *   Midianian - For creating UD Building State Colorizer. It gave me the idea for adding cade levels.
 *   Sean Dwyer - For the original AP recovery time concept that I saw.
 *   Vaevictus - For producing QuickLinks. It was the inspiration for what got me started on this.
 *
 */


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// General functions that retrieve information about the character and environment and variables for accessing it all //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// find out which page we're on
function getPage() {
	if(document.title.match(/Urban Dead - The City/)) return "city";
	else if(document.title.match(/Urban Dead - Skills Tree/)) return "skills";
	else if(document.title.match(/Urban Dead - Your Contacts List/) || document.title.match(/Urban Dead - Contacts List/)) return "contacts";
	else if(document.title.match(/Urban Dead - Profile/)) {
		if(location.href.indexOf("edit") != -1) return "settings";
        else if(document.evaluate("//p/a[@class='y' and contains(@href,'profile.cgi?mode=edit&id=')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength !== 0) return "your profile";
		else return "profile";
	}
	else if(document.title.match(/Urban Dead - Donation/)) return "donate";
	else if(document.title.match(/Urban Dead - FAQ/)) return "faq";
	else if(document.title.match(/Urban Dead - Game News/)) return "news";
	else if(document.title.match(/Urban Dead - Zombie Apocalypse/)) return "logout";
	else if(document.title.match(/Urban Dead - A Free Massively Multi/)) return "main";
	else if(document.title.match(/Urban Dead - Game Statistics/)) return "stats";
	else if(document.title.match(/Urban Dead - \$10 CPM Advertising/)) return "advertising";
	else if(document.title.match(/Urban Dead - Welcome to Malton/)) return "signup";
	return -1;
}


// grab character name, profile link, and profile id
function getCharacter() {
	var page = getPage();
	var character = [];
    var spans;

	if(page == "city") {
		var as = document.evaluate("//td[@class='cp']/div[@class='gt']/a", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

		if(as.snapshotLength !== 0) {
			character[0] = as.snapshotItem(0).innerHTML;
			character[1] = as.snapshotItem(0).href;
			character[2] = character[1].substring(character[1].indexOf("profile.cgi?id=") + 15);
			return character;
		}
	}
	else if(page == "profile") {
		spans = document.evaluate("//div[@class='gp']/h1/span[@class='ptt']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

		if(spans.snapshotLength !== 0) {
			character[0] = spans.snapshotItem(0).innerHTML;
			character[1] = location.href;
			character[2] = character[1].substring(character[1].indexOf("profile.cgi?id=") + 15);
			return character;
		}
	}
	else if(page == "your profile") {
		spans = document.evaluate("//div[@class='gp']/h1/span[@class='ptt']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		var editLink = document.evaluate("//p/a[@class='y' and contains(@href,'profile.cgi?mode=edit&id=')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

		if(spans.snapshotLength !== 0 && editLink.snapshotLength !== 0) {
			character[0] = spans.snapshotItem(0).innerHTML;
			character[1] = editLink.snapshotItem(0).href;
			character[2] = character[1].substring(character[1].indexOf("mode=edit&id=") + 13);
			return character;
		}
	}
    else if(page == "settings") {
		var h1s = document.evaluate("//div[@class='gp']/h1", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		var cancelLink = document.evaluate("//div[@class='gp']/form[@action='profile.cgi']/div/a[@class='y' and contains(@href,'profile.cgi?id=')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

		if(h1s.snapshotLength !== 0 && cancelLink.snapshotLength !== 0) {
			character[0] = h1s.snapshotItem(0).innerHTML.substring(8, h1s.snapshotItem(0).innerHTML.indexOf("'s"));
			character[1] = cancelLink.snapshotItem(0).href;
			character[2] = character[1].substring(character[1].indexOf("profile.cgi?id=") + 15);
			return character;
		}
	}
	character[0] = null;
	character[1] = null;
	character[2] = null;
	return character;
}


// grab the HP, XP, and AP values, as well as whether or not we're dead or infected
function getStats() {
	var bs = document.evaluate("//td[@class='cp']/div[@class='gt']//b", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var counter = 0;
	var stats = [];

	stats[3] = false;
	stats[4] = false;

	for(var i = 0; i < bs.snapshotLength; i++)
		if(!isNaN(parseInt(bs.snapshotItem(i).innerHTML)))
			stats[counter++] = parseInt(bs.snapshotItem(i).innerHTML);
		else if(bs.snapshotItem(i).innerHTML == "dead") stats[3] = true;
		else if(bs.snapshotItem(i).innerHTML == "infected") stats[4] = true;

	if(counter == 1) {
		stats[1] = -1;
		stats[2] = stats[0];
		stats[0] = -1;
	}
	else if(counter != 3) {
		stats[0] = -1;
		stats[1] = -1;
		stats[2] = 99;
	}
	return stats;
}


// grab the barricade level
function getCades() {
	// find the end of the correct sentence
	var gtTxt = document.evaluate("//td[@class='gp']/div[@class='gt']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

	if(ap <= 0) return -1;
	if(gtTxt.snapshotLength === 0) return -1;
	else gtTxt = gtTxt.snapshotItem(0).innerHTML;

	if(gtTxt.indexOf("extremely heavily barricaded") != -1) return 9;
	else if(gtTxt.indexOf("very heavily barricaded") != -1) return 8;
	else if(gtTxt.indexOf("heavily barricaded") != -1) return 7;
	else if(gtTxt.indexOf("very strongly barricaded") != -1) return 6;
	else if(gtTxt.indexOf("quite strongly barricaded") != -1) return 5;
	else if(gtTxt.indexOf("lightly barricaded") != -1) return 4;
	else if(gtTxt.indexOf("loosely barricaded") != -1) return 3;
	else if(gtTxt.indexOf("have been secured") != -1) return 2;
	else if(gtTxt.indexOf("has been ruined") != -1 || gtTxt.indexOf("has fallen into ruin") != -1 || gtTxt.indexOf("are ruined") != -1) return 0;
	else if(gtTxt.indexOf("left wide open") != -1 || gtTxt.indexOf("hang open") != -1 || gtTxt.indexOf("ragged rectangle has been cut") != -1 || gtTxt.indexOf("opens directly onto the street") != -1) return 1;
	else return -1;
}


// calculates the time (in 24-hour clock) that we'll be at full AP, roughly
function calculateTimeAtFullAP() {
	var startDate = new Date();
	var endDate = new Date();
	var extraMinutes = (50 - ap) * 30;
	var endTime = "";
	var endMinutes = startDate.getHours() * 60 + startDate.getMinutes() + extraMinutes;

	endMinutes -= endMinutes % 30;
	endMinutes = endMinutes % 1440;

	endDate.setSeconds(0);
	endDate.setMinutes(endMinutes % 60);
	endDate.setHours(endMinutes / 60);

	if(endDate.getHours() < 10) endTime += "0";
	endTime += endDate.getHours();
	if(endDate.getMinutes() < 10) endTime += "0";
	endTime += endDate.getMinutes();

	return endTime;
}


// figures out which abilities can be done at this location
function getLocalAbilities() {
	var localAbilities = [];
	localAbilities[0] = document.evaluate("//form[@action and contains(@action,'map.cgi?barricade')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[1] = document.evaluate("//form[@action and contains(@action,'map.cgi?dump')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[2] = document.evaluate("//form[@action and contains(@action,'map.cgi?fixgen')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[3] = document.evaluate("//form[@action and contains(@action,'map.cgi?fixrad')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[4] = document.evaluate("//form[@action and contains(@action,'map.cgi?repair')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[5] = document.evaluate("//form[@action and contains(@action,'map.cgi?close')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[6] = document.evaluate("//form[@action and contains(@action,'map.cgi?in')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[7] = document.evaluate("//form[@action and contains(@action,'map.cgi?out')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[8] = document.evaluate("//form[@action and contains(@action,'map.cgi?groan')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[9] = document.evaluate("//form[@action and contains(@action,'map.cgi?ransack')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[10] = document.evaluate("//form[@action and contains(@action,'map.cgi?rise')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	localAbilities[11] = document.evaluate("//form[@action and contains(@action,'map.cgi?search')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

	for(var i = 0; i < localAbilities.length; i++) {
		if(localAbilities[i].snapshotLength == 1) localAbilities[i] = localAbilities[i].snapshotItem(0);
		else localAbilities[i] = null;
	}
	return localAbilities;
}


// grabs the dump link
function getDumpButton() {
	var dumpForms = document.evaluate("//form[@action and contains(@action,'dump')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

	if(dumpForms.snapshotLength > 0) return dumpForms.snapshotItem(0);
	else return null;
}


// grabs the location's name
function getBlockName() {
	var bs = document.evaluate("//td[@class='gp']/div[@class='gt']/b", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

	if(bs.snapshotLength === 0) return -1;
	else return bs.snapshotItem(0).innerHTML;
}







// provide variables for accessing the data easily
var stats = getStats();
var character = getCharacter();
var localAbilities = getLocalAbilities();

var hp = stats[0];
var xp = stats[1];
var ap = stats[2];
var human = stats[3] === false ? true : false;
var zombie = !human && hp > 0 ? true : false;
var dead = zombie || hp === 0 ? true : false;
var alive = human;
var infected = stats[4];
var page = getPage();
var cades = getCades();
var charName = character[0];
var profileLink = character[1];
var charID = character[2];

var barricadeButton = localAbilities[0];
var dumpButton = localAbilities[1];
var fixGenButton = localAbilities[2];
var fixRadButton = localAbilities[3];
var repairButton = localAbilities[4];
var closeButton = localAbilities[5];
var enterButton = localAbilities[6];
var exitButton = localAbilities[7];
var groanButton = localAbilities[8];
var ransackButton = localAbilities[9];
var riseButton = localAbilities[10];
var searchButton = localAbilities[11];
var canBarricade = localAbilities[0] === null ? false : true;
var canDump = localAbilities[1] === null ? false : true;
var canFixGen = localAbilities[2] === null ? false : true;
var canFixRad = localAbilities[3] === null ? false : true;
var canRepair = localAbilities[4] === null ? false : true;
var canClose = localAbilities[5] === null ? false : true;
var canEnter = localAbilities[6] === null ? false : true;
var canExit = localAbilities[7] === null ? false : true;
var canGroan = localAbilities[8] === null ? false : true;
var canRansack = localAbilities[9] === null ? false : true;
var canRise = localAbilities[10] === null ? false : true;
var canSearch = localAbilities[11] === null ? false : true;

var blockName = getBlockName();













var barSize = 163;
var secondButtonBarUsed = false;
if(page == "city" || page == "skills" || page == "contacts" || page == "profile" || page == "your profile" || page == "settings") createMenuBar();

function createMenuBar() {
	var newMenu = document.createElement('div');
	var topBar = document.createElement('div');
	var botBar = document.createElement('div');
	var characterBox = document.createElement('div');
	var buttonBox = document.createElement('div');
	var secondButtonBox = document.createElement('div');

	document.body.insertBefore(newMenu,document.body.firstChild);
    newMenu.id="barrista";
	newMenu.setAttribute('style','margin: 0px 1px 0px 1px; height: 43px; width: 100%;');
	topBar.setAttribute('style','height: 28px; width: 100%; border: #454 solid 1px; border-width: 0px 0px 1px 0px; background-color: #232;');
	botBar.setAttribute('style','height: 15px; width: 100%;');
	document.body.setAttribute('style','margin: 0px 0px 0px 0px; padding: 0px;');

	buttonBox.setAttribute('style', 'margin: 0px; position: relative; float: right;');
	secondButtonBox.setAttribute('style', 'margin: 0px; position: relative; float: left;');

    var dumbwitType = "iSpy";
	if(page == "city") {
        var mainTable = document.evaluate("//table", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
        mainTable.setAttribute('style', 'margin-top: -15px;');
        characterBox.id="barristacharbox";
		characterBox.setAttribute('style', 'margin: 0px 2px 0px 2px; height: 25px; position: relative; float: left;');
		addCharInfo(characterBox);
		newMenu.appendChild(characterBox);
		addCadeInfo(newMenu);

		if(canSearch) {
			addButtonToMenu('Search the area', 'map.cgi?search', secondButtonBox, true, false);
			remove(searchButton);
		}

		if(dead) addButtonToMenu('Stand up', 'map.cgi?rise', secondButtonBox, true, false);

		if(canDump) {
			addButtonToMenu('Dump body', 'map.cgi?dump', secondButtonBox, true, false);
			remove(dumpButton);
		}

		if(canEnter) {
			addButtonToMenu('Enter ' + blockName, 'map.cgi?in', secondButtonBox, true, false);
			remove(enterButton);
		}
		else if(canExit) {
			addButtonToMenu('Exit ' + blockName, 'map.cgi?out', secondButtonBox, true, false);
			remove(exitButton);
		}

		addButtonToMenu('REFRESH', 'map.cgi?zoom', buttonBox, true, true);
	}
	else {
		if(page == "profile" || page == "your profile") {
            addButtonToMenu('ADD CONTACT', 'contacts.cgi?sort=colour&add=' + charID, buttonBox, true, true);
			addButtonToMenu('ROGUE\'S GALLERY', 'http://rg.urbandead.net/profiles/view/' + charID, buttonBox, true, true);
			addButtonToMenu('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;', '', buttonBox, false, true);
			dumbwitType += "PROFILE";
		}
        else if(page=="skills")
        {
            var h1 = document.evaluate("//h1", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
            h1.setAttribute('style', 'margin-top: -15px;');
        }

        if(page == "profile" || page == "your profile" || page == "contacts")
        {
            var profileDiv = document.evaluate("//div[@class='gp']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
            profileDiv.setAttribute('style', 'margin-top: -15px;');
        }
		addButtonToMenu('CITY', 'map.cgi?zoom', buttonBox, true, true);
	}

    addButtonToMenu('iSpy', dumbwitType, buttonBox, true, true);
	addButtonToMenu('WIKI', 'http://wiki.urbandead.com/', buttonBox, true, true);
	addButtonToMenu('SKILLS', 'skills.cgi', buttonBox, true, true);
	addButtonToMenu('CONTACTS', 'contacts.cgi?sort=colour', buttonBox, true, true);
	addButtonToMenu('SETTINGS', 'profile.cgi?mode=edit&id=' + charID, buttonBox, (page=="city" || page=="your profile" || page=="settings"), true);
	addButtonToMenu('LOGOUT', 'map.cgi?logout', buttonBox, true, true);

	topBar.appendChild(buttonBox);
	botBar.appendChild(secondButtonBox);
	newMenu.appendChild(topBar);
	newMenu.appendChild(botBar);
	removeButtons();
	removeGT();
}


function addCharInfo(characterBox) {
	var characterNameXP = document.createElement('div');
	var bars = document.createElement('div');
	var characterLink = document.createElement('a');
	var apBar = document.createElement('div');
	var apBarFill = document.createElement('div');
	var apBox = document.createElement('div');
	var hpBar = document.createElement('div');
	var hpBarFill = document.createElement('div');
	var hpBox = document.createElement('div');
	var xpBox = document.createElement('div');
	var apRecoveryXP = document.createElement('p');
	var xpLink = document.createElement('a');
	var apMax = 50;
	var hpMax = 60;

	if(ap != 99) apBox.innerHTML = ap + "AP";
	else {
		apBox.innerHTML = "AP";
		ap = 0;
	}

	if(hp != -1) hpBox.innerHTML = hp + "HP";
	else {
		hpBox.innerHTML = "HP";
		hp = 0;
	}

	// Fill the bars with various colors, depending on the ap/hp levels
    var apColor = '#f00';
	if(ap > 20) apColor = '#345';
	else if(ap >= 10) apColor = interpolateColor(ap, 20, 255, 0, 0, 171, 68, 85);
	else apColor = '#f00';

    var hpColor = '#f00';
	if(infected) hpColor = interpolateColor(hp, hpMax, 80, 140, 50, 100, 255, 0);		// special case: INFECTED
	else if(hp > 30) hpColor = '#898';
	else if(hp >= 10) hpColor = interpolateColor(hp, hpMax-30, 255, 0, 40, 230, 153, 136);
	else hpColor = '#f00';

	// Make the borders of the bars look duller as the bars get emptied
    var apBorder = '#bcb';
	if(ap >= 10 || ap === 0) apBorder = '#bcb';
	else apBorder = interpolateColor(ap, apMax, 136, 153, 136, 187, 204, 187);

    var hpBorder = '#bcb';
	if(infected) hpBorder = '#0f0';								// special case: INFECTED
	else if(hp > 30 || hp === 0) hpBorder = '#bcb';
	else hpBorder = interpolateColor(hp, hpMax-30, 136, 153, 136, 187, 204, 187);

    var apRightBorder = "";
    var hpRightBorder = "";
	if(ap < apMax && ap > 0) apRightBorder = "border-right: #fff solid 1px; ";
	if(hp < hpMax && hp > 0) hpRightBorder = "border-right: #fff solid 1px; ";

	if(xp != -1) {
		if(xp >= 1000) {
			var exact = false;
			if(Math.round(xp/1000) == xp/1000) exact = true;
			xpLink.innerHTML = (exact ? "" : "~") + Math.floor(xp/100)/10 + "K XP";
		}
		else xpLink.innerHTML = xp + "XP";
	}
	else xpLink.innerHTML = "XP";
	xpLink.href = "skills.cgi";
	apRecoveryXP.innerHTML = calculateTimeAtFullAP() + "|";

    characterNameXP.id="barristacharinfo";
	characterNameXP.setAttribute('style','margin: 0px; height: 27px; float: left; text-align: right; overflow: hidden; padding: 1px 5px 0px 5px; font-size: .7em; font-weight: bold;');
	apRecoveryXP.setAttribute('style', 'margin: 0px;');

    bars.id="barristabar";
	bars.setAttribute('style', 'margin: 0px; height: 25px; float: left;');

    apBar.id="barristaap";
	apBar.setAttribute('style','margin: 0px; height: 10px; width: ' + (barSize+28) + 'px; border: ' + apBorder + ' solid 1px; float: left; position: relative; top: 1px; background-color: #454;');

    hpBar.id="barristahp";
	hpBar.setAttribute('style','margin: 0px; height: 10px; width: ' + (barSize+28) + 'px; border: ' + hpBorder + ' solid 1px; float: left; position: relative; top: 2px; background-color: #454; clear: left;');

    apBox.id="barristaaptext";
	apBox.setAttribute('style','margin: 0px; height: 100%; width: 24px; position: relative; float: left; color: #fff; font-size: 9px; text-align: right; padding-right: 3px; border-right: #fff solid 1px; background-color: #454;');

    hpBox.id="barristahptext";
	hpBox.setAttribute('style','margin: 0px; height: 100%; width: 24px; position: relative; float: left; color: ' + (infected ? '#0f0' : '#fff') + '; font-size: 9px; text-align: right; padding-right: 3px; border-right: #fff solid 1px; background-color: #454;');

    apBarFill.id="barristaapbar";
	apBarFill.setAttribute('style','margin: 0px; height: 100%; width: ' + (ap/apMax * barSize) + 'px; position: relative; float: left; background-color: ' + apColor + ';' + apRightBorder);

    hpBarFill.id="barristahpbar";
	hpBarFill.setAttribute('style','margin: 0px; height: 100%; width: ' + (hp/hpMax * barSize) + 'px; position: relative; float: left; background-color: ' + hpColor + ';' + hpRightBorder);

	characterLink.innerHTML = charName + '<br />';
	characterLink.className = "barristaCharName";
	characterLink.href = profileLink;

	apBar.appendChild(apBox);
	hpBar.appendChild(hpBox);
	apBar.appendChild(apBarFill);
	hpBar.appendChild(hpBarFill);

	characterNameXP.appendChild(characterLink);
	bars.appendChild(apBar);
	characterNameXP.appendChild(apRecoveryXP);
	bars.appendChild(hpBar);
	apRecoveryXP.appendChild(xpLink);
	characterBox.appendChild(characterNameXP);
	characterBox.appendChild(bars);
}


function addCadeInfo(newMenu) {
	var cadeColors = [];

	if(cades == -1) return;

	cadeColors[0] = "#333";
	cadeColors[1] = "#a00";
	cadeColors[2] = "#f33";
	cadeColors[3] = "#fa3";
	cadeColors[4] = "#ff3";
	cadeColors[5] = "#af3";
	cadeColors[6] = "#3fa";
	cadeColors[7] = "#3ff";
	cadeColors[8] = "#3af";
	cadeColors[9] = "#bcb";

    var cadeBlock;
    var cadeBorder;
    var size;

	if(canBarricade) {
		cadeBlock = document.createElement('a');
		cadeBorder = "3px double #232";
		cadeBlock.href = barricadeButton.action;
		remove(barricadeButton);
		size = 19;
		if(canBarricade)
			cadeBlock.innerHTML = "cade";
		else
			cadeBlock.innerHTML = "close";
		cadeBlock.className = "barricade";
		cadeBlock.setAttribute("onmouseover", 'this.style.backgroundColor = "#fff"');
		cadeBlock.setAttribute("onmouseout", 'this.style.backgroundColor = "' + cadeColors[cades] + '"');
	}
	else {
		cadeBlock = document.createElement('div');
		cadeBorder = "1px solid #bcb";
		size = 23;
	}

    cadeBlock.id="barristabarricade";
	cadeBlock.setAttribute('style','display: block; margin: 0px; height: ' + size + 'px; width: ' + size + 'px; position: relative; float: left; top: 1px; border: ' + cadeBorder + '; background-color: ' + cadeColors[cades] + '; color: #232; font-size: 9px; text-align: center;');

	newMenu.appendChild(cadeBlock);
}


function addButtonToMenu(name, link, buttonBox, valid, top) {
	var styles = [];
	var styleCounter = 0;

	styles[0] = 'display: block; position: relative; float: left; font-size: 15px; padding: 5px 1em 5px 1em; border-left: 1px solid #454; border-right: 1px solid #898; font-weight: 500;';
	styles[1] = 'position: relative; float: left; font-size: 15px; padding: 5px 1em 5px 1em; border-left: 1px solid #454; border-right: 1px solid #898; font-weight: 400; background-color: #444; color: #666;';
	styles[2] = 'display: block; position: relative; float: left; font-size: 9px; padding: 2px .5em 2px .5em; border-left: 1px solid #454; border-right: 1px solid #898; border-bottom: 1px solid #454; font-weight: 500; background-color: #232;';
	styles[3] = 'position: relative; float: left; font-size: 9px; padding: 5px 1em 5px 1em; border-left: 1px solid #454; border-right: 1px solid #454; border-bottom: 1px solid #454; font-weight: 400; background-color: #444; color: #666;';

	if(!top) {
		styleCounter = 2;
		secondButtonBarUsed = true;
	}

    var button;
	if(valid) {
		button = document.createElement('a');

		button.setAttribute('style', styles[0 + styleCounter]);
		button.setAttribute("onmouseover", "this.style.backgroundColor = '#676'");
		button.setAttribute("onmouseout", "this.style.backgroundColor = '#232'");

        // If this is a dumbwit link, set up a special onclick event, otherwise set the link as the href
        if( link == "iSpy" )
        {
            button.setAttribute("onclick", "exportToDumbwit(btoa(unescape(encodeURIComponent(document.body.innerHTML))),window.document.lastModified,'ead.com/map.c')");
            button.href = "#";
        }
        else if( link == "iSpyPROFILE" )
        {
            button.setAttribute("onclick", "exportToDumbwit(btoa(unescape(encodeURIComponent(document.body.innerHTML))),window.document.lastModified,'ead.com/profile.c')");
            button.href = "#";
        }
        else
        {
            button.href = link;
        }
		button.className = "barristaButton";
	}
	else {
		button = document.createElement('div');
		button.setAttribute('style', styles[1 + styleCounter]);
	}

	button.innerHTML = name;
	buttonBox.appendChild(button);
}


exportToDumbwit = function(source, lastModified, hrefCheck)
{
    var dwDate = new Date();
    var dwWindow = window.open('', dwDate.toString().replace(/[\W]/g, ''));
    var dwComments = prompt("Comment for the Dumbwit (may be left blank):");
    dwWindow.document.write("<HTML><BODY><FORM accept-charset='UTF-8' NAME='wF' ACTION='https://ispy.dxavier.net/add/wit.php' METHOD='POST'><INPUT type='hidden' NAME='wP' VALUE='PRIVATE'>Enter iSpy Comment - may be blank</br></br><INPUT NAME='wC' VALUE=''><INPUT type='hidden' NAME='wT' VALUE='" + lastModified + "'><INPUT type='hidden' NAME='wZ' VALUE='" + dwDate.getTimezoneOffset() + "'><INPUT type='hidden' NAME='wV' VALUE='23'><TEXTAREA style='display:none;' NAME='wS'>" + source + "</TEXTAREA><input type='submit'>");
	var u = window.location.href.indexOf(hrefCheck);
    if( 12 < u && u < 18){
	}else{
		alert('Wrong website! This only works on UrbanDead!');
	}
};


function interpolateColor(value, max, r1, g1, b1, r2, g2, b2) {
	var c = [[r1, g1, b1], [r2, g2, b2]];
	var level = value / max;
	var color = '#';

	for (var i = 0; i < 3; ++i)
		color += ('0' + parseInt(c[0][i] + ((c[1][i] - c[0][i]) * level)).toString(16)).substr(-2);

	return color;
}


function removeButtons() {
	var pars = document.evaluate("//a[@class='y']/parent::p", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	if(pars.snapshotLength !== 0)
		for(var i = 0; i < pars.snapshotLength; i++) {
			remove(pars.snapshotItem(i));
		}
}


function removeGT() {
	var pars = document.evaluate('//tr/td[@class="cp"]/div[@class="gt"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	if(pars.snapshotLength !== 0) {
		var spacer = document.createElement('div');
		spacer.setAttribute('style', 'margin: 0px; height: 14px; width: 100%;');
		if(secondButtonBarUsed) pars.snapshotItem(0).parentNode.insertBefore(spacer, pars.snapshotItem(0).parentNode.childNodes[0]);
		remove(pars.snapshotItem(0));
	}
}


function remove(removeTarget) {
	removeTarget.setAttribute('style','display: none;');
}