Planets.nu Hover Prediction

NU Starmap-Plugin, that hovers more info for Planets, Ships and Minerals also for the next turn

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name          Planets.nu Hover Prediction
// @namespace     quapla/Hover Prediction
// @date          2016-05-26
// @author        Quapla
// @grant         none
// @description   NU Starmap-Plugin, that hovers more info for Planets, Ships and Minerals also for the next turn
// @include       http://planets.nu/home
// @include       http://planets.nu/games/*
// @include       http://play.planets.nu/*
// @include       http://*.planets.nu/*
// @include       http://planets.nu/*
// @homepage      https://greasyfork.org/de/scripts/19831-planets-nu-hover-prediction
// @version       0.4.10
// ==/UserScript==

// Reference Jim Clark's Planets.nu improved hover text (V2): https://greasyfork.org/en/scripts/2618-planets-nu-improved-hover-text
// Reference Big Beefer's Planet.nu improved hovertext (V3): https://greasyfork.org/en/scripts/2618-planets-nu-improved-hover-text
// Reference Stephen Piper's hoverTextbox: https://greasyfork.org/en/scripts/17959-hovertextbox
// Reference helmet's Planets.nu ship predictor: http://userscripts-mirror.org/scripts/show/146137
// Reference Kero van Gelder: Redraw and Filter: http://chmeee.org/ext/planets.nu/RedrawAndFilter.user.js
// Colaboration kedalion's Enemy Ship List Plugin: https://greasyfork.org/en/scripts/5994-planets-nu-enemy-ship-list-plugin

/*------------------------------------------------------------------------------
0.1 Initial Workout
0.2 Impelemntation of Jim Clark's and Big Beefer's code
0.3 Implementation of Stephen Piper's code
0.3 New Layout and diferent point of views
0.4 Implementation of helmet's code - Official Beta Release to start communication
0.4.3 Changed views, planned planets/ships are now green, added more settings (take care to click the checkboxes!)
0.4.4 Fixed bdm/bum cases
0.4.8 Changed views, added Enemey-Ships, and VPA-style net cargo info in brackets. Colaboration with Enemy Ship
0.4.10 Bugfix, thanx to Frostriese
------------------------------------------------------------------------------*/

function wrapper() { // wrapper for injection
	// Functions for Show Hover
	function hitText() {}

	hitText.prototype = {
		nativeTaxAmount : function (c, ntr) // How much do natives pay at 'c' with 'ntr'-taxrate - limited by natives/taxrate
		{
			var nt = 0;
			if (c.nativeclans > 0) {
				if (c.race == 6 && ntr > 20) { // borg == 6 can be taxed with 20% max
					ntr = 20;
				}

				nt = (c.nativeclans / 100) * (ntr / 10) * (c.nativegovernment / 5);

				nt = c.nativetype == 5 ? 0 : nt; // amorphous == 5 wont pay
				nt *= c.race == 1 ? 2 : 1; // feds == 1 pay twice
				nt *= c.nativetype == 6 ? 2 : 1; // insect == 6 pay twice

				nt = Math.round(nt);
			}
			return nt;
		},

		nativesupportedtax : function (c) // How taxes can we receive at 'c' - limited by clans
		{
			var ns = c.clans;
			ns *= c.race == 1 ? 2 : 1; // feds == 1
			ns *= c.nativetype == 6 ? 2 : 1; // insect == 6
			return ns;
		},

		showMin : function (txt, surface, change, ground, chtxt) // Shows | 00000000 | TXT | CHTXT 0000 | (00000)
		{
			var showtxt = "<td style='text-align:right;'>" + addCommas(surface) + "&nbsp</td>";
			showtxt += "<td>" + txt + "&nbsp</td>";
			showtxt += "<td style='text-align:right;'>&nbsp" + chtxt + addCommas(change, true) + "&nbsp</td>";
			showtxt += "<td style='text-align:right;";
			if (ground < 100) {
				showtxt += " color:#ff0000;";
			} // Red
			else if (ground < 1000) {
				showtxt += " color:#ffa500;";
			} // Orange
			else if (ground > 10000) {
				showtxt += " color:#90ee90;";
			} // Green
			showtxt += "'>&nbsp(" + addCommas(ground) + ")</td>";
			return showtxt;
		},

		// Reference: Redraw and Filter, Kero van Gelder, http://chmeee.org/ext/planets.nu/RedrawAndFilter.user.js
		shortHullName : function (hull) {
			var name;
			switch (hull.id) {
			case 15:
				return "SDSF";
			case 16:
				return "MDSF";
			case 17:
				return "LDSF";
			case 18:
				return "STF";
			case 28:
				return "Fearless";
			case 69:
				return "SSD";
			default:
				if (hull.id >= 1000)
					return hull.name;
				var hullName = hull.name;
				var m;
				if (m = hullName.match(/^(([^ ]+).*) Class /))
					name = m[2].match(/\d/) ? m[2] : m[1];
				else if (m = hullName.match(/^(([^ ]+) [^ ]+)/))
					name = m[2].match(/\d/) ? m[2] : hullName;
				else
					name = hullName;
				return name;
			}
		},

		GetMaxPop : function (hit) // Gets max. Population on Planet hit
		{
			/// Population in popup text
			//////////////////////
			var planetOwner = null;
			var maxPop = 0;

			// Do we have a temp scan?
			if (hit.temp >= 0 && hit.temp <= 100) {
				// Use your race if planet unowned
				if (hit.ownerid == 0)
					planetOwner = vgap.getPlayer(vgap.player.id);
				else
					planetOwner = vgap.getPlayer(hit.ownerid);
				// Find max pop
				// xtal
				if (planetOwner.raceid == 7) {
					maxPop = 1000 * hit.temp;
				} else {
					maxPop = Math.round(Math.sin(3.14 * (100 - hit.temp) / 100) * 100000);
					if (hit.temp > 84)
						maxPop = Math.floor((20099.9 - (200 * hit.temp)) / 10);
					if (hit.temp < 15)
						maxPop = Math.floor((299.9 + (200 * hit.temp)) / 10);
					// Cols, Rebles, Fascists, Bots
					if (hit.temp > 80 && (planetOwner.raceid == 4 || planetOwner.raceid == 9 || planetOwner.raceid == 10 || planetOwner.raceid == 11))
						maxPop = 60;
					// Rebels
					if (hit.temp <= 19 && planetOwner.raceid == 10)
						maxPop = 90000;
				}

				if (hit.debrisdisk > 0) {
					maxPop = 0;
					if (vgap.getStarbase(maxPop.id) != null) {
						maxPop = 500;
					}
				}
			}
			return maxPop;

		},

		GetPopGrowth : function (hit) // Gets growth of Population
		{
			var planet = hit;
			var player = vgap.getPlayer(hit.ownerid);
			var raceId = player.raceid;

			var colGrowth = 0;
			if ((planet.colonisthappypoints + vgap.colonistTaxChange(planet)) >= 70 && planet.clans > 0) {
				var colMax = Math.round(Math.sin(3.14 * (100 - planet.temp) / 100) * 100000);

				//crystals like it hot
				if (raceId == 7) {
					colMax = 1000 * planet.temp;
					colGrowth = Math.round(((planet.temp / 100) * (planet.clans / 20) * (5 / (planet.colonisttaxrate + 5))));
					if (vgap.advActive(47))
						colGrowth = Math.round((((planet.temp * planet.temp) / 4000) * (planet.clans / 20) * (5 / (planet.colonisttaxrate + 5))));
				} else if (planet.temp >= 15 && planet.temp <= 84)
					colGrowth = Math.round(Math.sin(3.14 * ((100 - planet.temp) / 100)) * (planet.clans / 20) * (5 / (planet.colonisttaxrate + 5)));

				//slows down over 6,600,000
				if (planet.clans > 66000)
					colGrowth = Math.round(colGrowth / 2);

				//planetoids do not have an atmosphere
				if (planet.debrisdisk > 0)
					colGrowth = 0;

				//check against max
				if ((planet.clans + colGrowth) > colMax)
					colGrowth = colMax - planet.clans;

				//100 and 0 degree planets
				if (colGrowth < 0)
					colGrowth = 0;
			}

			if (colGrowth == 0)
				colGrowth = this.GetsmaxPop(hit, true);

			if (planet.nativetype == 5) // angry Amorphs...
				if (hit.nativetaxrate + vgap.nativeTaxChange(planet) >= 70)
					colGrowth -= 5;
				else if (hit.nativetaxrate + vgap.nativeTaxChange(planet) >= 70)
					colGrowth -= 20;
				else
					colGrowth -= 40;

			return colGrowth;
		},

		GetMinPopGrow : function (hit) {
			var player = vgap.getPlayer(hit.ownerid);
			var raceId = player.raceid;
			var planet = hit;
			var grow = 1;

			if (planet.nativetype == 5) // angry Amorphs...
					grow += 5;

			for (i = 1; i<300; i++) {
				if (raceId == 7) {
					if (vgap.advActive(47))
						colGrowth = Math.round((((planet.temp * planet.temp) / 4000) * (i / 20) * (5 / (planet.colonisttaxrate + 5))));
					else
						colGrowth = Math.round(((planet.temp / 100) * (i / 20) * (5 / (planet.colonisttaxrate + 5))));
				} else {
					if (planet.temp >= 15 && planet.temp <= 84)
						colGrowth = Math.round(Math.sin(3.14 * ((100 - planet.temp) / 100)) * (i / 20) * (5 / (planet.colonisttaxrate + 5)));
					else {
						colGrowth = 0;
						break;
					}
				}
				if (colGrowth >= grow)
					break;
			}
			if (i >= 299 || colGrowth == 0)
				i = 0;
			return i;
		},

		GetsmaxPop : function (hit, getGrowth) { // getGrows: TRUE Col growth, FALSE: max supported
			var player = vgap.getPlayer(hit.ownerid);
			var raceId = player.raceid;
			var planet = hit;
			var climateDeathRate = 10;
			var maxSupported = 0;
			var colGrowth = 0;

			//crystal calculation
			if (raceId == 7)
				maxSupported = planet.temp * 1000;
			else {
				//all others
				maxSupported = Math.round(Math.sin(3.14 * (100 - planet.temp) / 100) * 100000);
				if (planet.temp > 84)
					maxSupported = Math.floor((20099.9 - (200 * planet.temp)) / climateDeathRate);
				else if (planet.temp < 15)
					maxSupported = Math.floor((299.9 + (200 * planet.temp)) / climateDeathRate);
			}

			//Fascist, Robots, Rebels, Colonies can support a small colony of 60 clans on planets over 80 degrees
			if (raceId == 4 || raceId == 9 || raceId == 10 || raceId == 11) {
				if (planet.temp > 80)
					maxSupported = Math.max(maxSupported, 60);
			}

			//rebel arctic planet advantage
			if (planet.temp <= 19 && raceId == 10)
				maxSupported = Math.max(maxSupported, 90000);

			//planetoids do not have an atmosphere
			if (planet.debrisdisk > 0) {
				maxSupported = 0;
				if (vgap.getStarbase(planet.id) != null)
					maxSupported = 500;
			}

			if (!getGrowth)
				return maxSupported;

			//determine how much we are overpopulated
			var overPopulation = Math.ceil((planet.clans - maxSupported) * (climateDeathRate / 100));
			if (overPopulation > 0) {
				//recalculate maxsupported/overpopulation
				maxSupported = maxSupported + Math.round(planet.supplies * 10 / 40);
				overPopulation = Math.ceil((planet.clans - maxSupported) * (climateDeathRate / 100));

				//update population
				colGrowth = -1 * Math.max(0, overPopulation);
			}
			return colGrowth;
		},

		GetMinPop : function (hit) // Gets minimal Population on Hit
		{
			/// Population in popup text
			//////////////////////
			var planetOwner = null;
			var minPop = 0;

			// Do we have a temp scan?
			if (hit.temp >= 0 && hit.temp <= 100) {

				// Use your race if planet unowned
				if (hit.ownerid == 0)
					planetOwner = vgap.getPlayer(vgap.player.id);
				else
					planetOwner = vgap.getPlayer(hit.ownerid);

				// Find min growth pop
				var targetGrowth = 1;
				// Worms!
				if (hit.nativetype == 5)
					targetGrowth = 6;
				// xtal
				if (planetOwner.raceid == 7) {
					minPop = Math.floor(targetGrowth * 11 / (hit.temp / 100));
					if (vgap.advActive(47)) {
						minPop = Math.floor(targetGrowth * 11 / hit.temp * hit.temp / 4000);
					}
					if (hit.temp < 15)
						minPop = 0;

				} else {
					// This should just be a formula like: minPop = Math.floor(targetGrowth * 11 / Math.sin(3.14*(100-hit.temp)/100)));
					// But that is off but a bit. This seems more acurate, but is still slightly off the chart I was going off. Which may be wrong too!
					// ...
					for (minPop = 10; minPop < 300; minPop++) {
						var growth = Math.round(Math.sin(3.14 * ((100 - hit.temp) / 100)) * minPop / 20);
						if (growth >= targetGrowth)
							break;
					}
					if (hit.temp < 15 || hit.temp > 84)
						minPop = 0;
					if (minPop >= 299)
						minPop = 0;
				}

				if (hit.debrisdisk > 0) {
					minPop = 0;
				}

			}
			//////////////////////
			return minPop;
		},

		miningRate(p, ground, density, mines) {
			m = vgap.miningRate(p, density, mines);
			m = m > ground ? ground : Math.round(m);
			return m;
		},

		getDistQ : function (x1, y1, x2, y2) {
			var dx = x2 - x1;
			var dy = y2 - y1;
			return Math.sqrt((dx * dx) + (dy * dy));
		},

	};

	hitText.prototype.predictor = function (ship, forTowCalculation) { //be careful when calling 'this', needs the actual shipscreen!
		if (!ship)
			return;
		var hull = vgap.getHull(ship.hullid);
		var planet = vgap.planetAt(ship.x, ship.y);
		var starbase = null;
		if (planet)
			starbase = vgap.getStarbase(planet.id);
		var result = {
			ammo : 0,
			supplies : 0,
			neutronium : 0,
			duranium : 0,
			tritanium : 0,
			molybdenum : 0,
			megacredits : 0,
			damage : 0,
			crew : 0,
			cargo : 0
		};
		var getCargo = function () {
			result.cargo = result.ammo + result.supplies + result.duranium + result.tritanium + result.molybdenum;
		};
		var cloakFuel = function () {
			if ((ship.mission == 9 || (vgap.player.raceid == 3 && ship.mission == 8 && hull.cancloak)) && ship.hullid != 29 && ship.hullid != 31)
				return Math.max(5, Math.floor((hull.mass / 100) * 5));
			else
				return 0;
		}

		//cloak - will it use fuel when it fails because of lack of fuel?
		result.neutronium -= Math.min(ship.neutronium + result.neutronium, cloakFuel());

		//build fighters
		getCargo();
		if (ship.bays > 0 && vgap.player.raceid > 8) {
			var race = vgap.player.raceid;
			var loadedfighters = 0;
			//load
			if (planet != null && planet.ownerid == vgap.player.id && ship.friendlycode.toUpperCase() == "LFM" && ship.neutronium + result.neutronium > 0) {
				loadedfighters = Math.min(Math.floor(planet.molybdenum / 2), Math.floor(planet.tritanium / 3), Math.floor(planet.supplies / 5), Math.floor((hull.cargo - vgap.shipScreen.getTotalCargo(ship) - result.cargo) / 10));
				if (loadedfighters > 0) {
					result.molybdenum += loadedfighters * 2;
					result.tritanium += loadedfighters * 3;
					result.supplies += loadedfighters * 5;
				}
			}
			//build
			var builtfighters = 0;
			if ((ship.friendlycode.toUpperCase() == "LFM" && ship.neutronium + result.neutronium > 0) || ((race == 9 || race == 11) && ship.mission == 8)) {
				builtfighters = Math.min(Math.floor((ship.molybdenum + result.molybdenum) / 2), Math.floor((ship.tritanium + result.tritanium) / 3), Math.floor((ship.supplies + result.supplies) / 5));
				if (builtfighters > 0) {
					result.molybdenum -= builtfighters * 2;
					result.tritanium -= builtfighters * 3;
					result.supplies -= builtfighters * 5;
					result.ammo += builtfighters;
				}
			}
		}

		//lady royale
		if (hull.id == 42 && ship.neutronium > 0) {
			result.megacredits += Math.min(10000 - (ship.megacredits + result.megacredits), ship.clans + result.clans);
		}

		//borg repair
		if (vgap.player.raceid == 6 && ship.mission == 8 && ship.neutronium > 0 && ship.warp == 0)
			result.damage -= Math.min(ship.damage, 10);

		//bdm -> Ship 0 gets 0 MC, Planet get all MC for later bum...
		var bdm = 0;
		if (planet != null) {
			if (ship.friendlycode.toUpperCase() == "BDM")
				result.megacredits -= (ship.megacredits + result.megacredits);
			var shipsAt = vgap.shipsAt(ship.x, ship.y);
			for (var i = 0; i < shipsAt.length; i++) {
				var s = shipsAt[i];
				if (s.ownerid != vgap.player.id && !s.allyupdate) // try (vgap.allied(s.ownerid))
					continue;
				if (s.friendlycode.toUpperCase() == "BDM") {
					bdm += s.megacredits;
					if (s.allyupdate && s.hullid == 42 && s.neutronium > 0)
						bdm += Math.min(10000 - s.megacredits, s.clans); //allied Lady Royale
				}
			}
		}

		//bum
		if (planet != null && (planet.ownerid == 0 || planet.ownerid == vgap.player.id || planet.allyupdate) && planet.friendlycode.toUpperCase() == "BUM") {
			var bum = planet.megacredits + bdm;
			for (var i = 0; i < shipsAt.length; i++) {
				var s = shipsAt[i];
				if (s.id < ship.id && s.ownerid != vgap.player.id && !s.allyupdate) {
					bum = 0; //can't handle foreign ships
					break;
				}
				if (s.id < ship.id)
					bum -= Math.min(10000 - (s.friendlycode.toUpperCase() == "BDM" ? 0 : s.megacredits), bum);
				else
					break;
			}
			if (bum > 0)
				result.megacredits += bum;
		}

		//gather missions (2do: other ships gathering before)
		getCargo();
		if (ship.neutronium > 0 && ship.mission > 9 && ship.mission < 15 && planet != null && (planet.ownerid == 0 || planet.ownerid == vgap.player.id)) { //2do? allied
			freecargo = hull.cargo - vgap.shipScreen.getTotalCargo(ship) - result.cargo;
			switch (ship.mission) {
			case 10:
				if (planet.neutronium > 0)
					result.neutronium += Math.min(hull.fueltank - ship.neutronium - result.neutronium, planet.neutronium);
				break;
			case 11:
				if (planet.duranium > 0)
					result.duranium += Math.min(freecargo, planet.duranium);
				break;
			case 12:
				if (planet.tritanium > 0)
					result.tritanium += Math.min(freecargo, planet.tritanium);
				break;
			case 13:
				if (planet.molybdenum > 0)
					result.molybdenum += Math.min(freecargo, planet.molybdenum);
				break;
			case 14:
				if (planet.supplies > 0)
					result.supplies += Math.min(freecargo, planet.supplies);
				break;
			default:
				break;
			}
		}

		//alchemy
		if (hull.id == 105 && ship.friendlycode.toLowerCase() != "nal" && ship.neutronium > 0) //need fuel for that?
		{
			var alchemy = Math.floor((ship.supplies + result.supplies) / 9);
			result.supplies -= 9 * alchemy;
			switch (ship.friendlycode.toLowerCase()) {
			case "ald":
				result.duranium += 3 * alchemy;
				break;
			case "alt":
				result.tritanium += 3 * alchemy;
				break;
			case "alm":
				result.molybdenum += 3 * alchemy;
				break;
			default:
				result.duranium += alchemy;
				result.tritanium += alchemy;
				result.molybdenum += alchemy;
				break;
			}
		}

		getCargo();
		//refinery NRS=104, Aries=97
		if ((hull.id == 104 || hull.id == 97) && ship.friendlycode.toLowerCase() != "nal" && ship.neutronium > 0) { //need fuel for that?
			var ref = Math.min(ship.duranium + result.duranium + ship.tritanium + result.tritanium + ship.molybdenum + result.molybdenum, hull.fueltank - (ship.neutronium + result.neutronium));
			if (hull.id == 104) {
				ref = Math.min(ref, ship.supplies);
				result.supplies -= ref;
			}
			result.neutronium += ref;
			//how it's done
			var now = Math.min(ship.duranium + result.duranium, ref);
			result.duranium -= now;
			ref -= now;
			now = Math.min(ship.tritanium + result.tritanium, ref);
			result.tritanium -= now;
			ref -= now;
			now = Math.min(ship.molybdenum + result.molybdenum, ref);
			result.molybdenum -= now;
			ref -= now;
			if (ref != 0) { //whoops, something went wrong
			}

			/* that's how I'd do it...
			var a=[ship.duranium,ship.tritanium,ship.molybdenum];
			var k=0;
			while (ref>0) {
			if (a[k]>0) {a[k]--; ref--};
			k=(k+1)%3;
			}

			result.duranium-=ship.duranium-a[0];
			result.tritanium-=ship.tritanium-a[1];
			result.molybdenum-=ship.molybdenum-a[2];
			 */
		}

		getCargo();
		//lay mines
		if (ship.mission == 2 || (vgap.getPlayer(ship.ownerid).raceid == 7 && ship.mission == 8))
			// result.ammo -= vgap.shipScreen.getMineLayTorps(ship);  // Quapla to Todo: No function getMineLayTorps
			result.ammo = 0;
		getCargo();

		//scoop mines

		//create array of proposed minefields first
		if (ship.torps > 0 && ship.mission == 1 && ship.friendlycode.toLowerCase() == "msc") {
			var minefields = new Array();
			for (var j = 0; j < vgap.minefields.length; j++) {
				var mf = vgap.minefields[j];
				minefields.push({
					ownerid : mf.ownerid,
					x : mf.x,
					y : mf.y,
					radius : mf.radius,
					isweb : mf.isweb,
					units : mf.units,
					radiusPresweep : mf.radius
				});
			}
			//mine laying minefields (from preview)
			for (var i = 0; i < vgap.ships.length; i++) {
				var s = vgap.ships[i];
				if (s.ownerid != vgap.player.id && !s.allyupdate)
					continue;
				if (s.neutronium > 0 && s.ammo > 0 && s.torps > 0) {
					if (s.mission == 2 || (s.mission == 8 && vgap.player.raceid == 7)) {
						var isWeb = (s.mission == 8);

						var fieldOwnerId = s.ownerid;

						//miX friendlycode
						if (s.friendlycode.toLowerCase().indexOf("mi") === 0) {
							fieldOwnerId = vgap.getPlayerIdVal(s.friendlycode.toLowerCase().replace("mi", ""));
							if (fieldOwnerId == 0 || fieldOwnerId > vgap.game.slots)
								fieldOwnerId = s.ownerId;
						}
						var units = this.getMineUnits(s);

						//determine if we are inside of one of our minefields
						var minefield = null;
						var closest = 10000.0;
						for (var j = 0; j < minefields.length; j++) {
							var closestField = minefields[j];
							if (closestField.isweb == isWeb && closestField.ownerid == fieldOwnerId) {
								var dist = parseFloat(hitText.prototype.getDistQ(s.x, s.y, closestField.x, closestField.y)); // Quapla Todo
								// var dist = 9999; // never in Minefield -> Check funktion getDist Quapla
								if (dist < closest) {
									minefield = closestField;
									closest = dist;
								}
								if (closest == 0)
									break;
							}
						}
						var newField = true;
						if (minefield != null) {
							if (closest <= minefield.radius)
								newField = false;
						}
						//new field
						if (newField) {
							minefield = {
								ownerid : fieldOwnerId,
								x : s.x,
								y : s.y,
								isweb : isWeb,
								units : 0
							};
							minefields.push(minefield);
						}

						//add the units to the minefield
						minefield.units += units;
						minefield.changed = 1;

						//max minefield, don't lay so many torps
						if (minefield.units > 22500)
							minefield.units = 22500;

						minefield.radius = Math.sqrt(minefield.units);

					}
				}

			}
			var torp = vgap.getTorpedo(ship.torpedoid);
			getCargo();
			var openCargo = 0;
			var ammo = 0;
			//look for scooping ships
			for (var i = 0; i < vgap.ships.length; i++) {
				var s = vgap.ships[i];
				if (s.ownerid != vgap.player.id && !s.allyupdate)
					continue;
				if (s.friendlycode.toLowerCase() != "msc" || s.mission != 1 || s.torps < 1 || s.beams < 1 || s.neutronium < 1)
					continue;
				openCargo = vgap.getHull(s.hullid).cargo - vgap.shipScreen.getTotalCargo(s);
				if (s.id == ship.id)
					openCargo -= result.cargo; //2do? result for other ships
				for (var j = 0; j < minefields.length; j++) {
					var minefield = minefields[j];
					var dist = parseFloat(hitText.prototype.getDistQ(s.x, s.y, minefield.x, minefield.y));
					if (minefield.ownerid == s.ownerid && (dist - minefield.radius) <= 0) {
						//Mine scoop
						var unitsScooped = openCargo * s.torpedoid * s.torpedoid;
						if (vgap.player.raceid == 9)
							unitsScooped *= 4;

						if (unitsScooped > minefield.units)
							unitsScooped = minefield.units;

						if (unitsScooped > 0) {
							minefield.units -= unitsScooped;
							minefield.radius = Math.sqrt(minefield.units);
							minefield.swept = 1;
							if (minefield.units < 0)
								minefield.units = 0;

							if (vgap.player.raceid == 9)
								unitsScooped /= 4;

							ammo = Math.floor(unitsScooped / s.torpedoid / s.torpedoid);

							openCargo -= ammo;
							if (s.id == ship.id)
								result.ammo += ammo;
						}
					}
				}
				if (s.id == ship.id)
					break;
			}
		}

		//Starbase fix
		if (starbase && starbase.shipmission == 1 && starbase.targetshipid == ship.id) {
			result.damage -= ship.damage;
			result.crew += hull.crew - ship.crew;
		}

		//repair with supplies
		if (ship.damage + result.damage > 0) {
			var rep = Math.floor(ship.supplies / 5);
			rep = Math.min(rep, ship.damage + result.damage);
			result.supplies -= rep * 5;
			result.damage -= rep;
		}

		//mkt
		if (ship.torps > 0 && ship.friendlycode.toUpperCase() == "MKT") {
			var cost = vgap.getTorpedo(ship.torpedoid).torpedocost;
			var mkt = Math.min(ship.duranium + result.duranium, ship.tritanium + result.duranium, ship.molybdenum + result.molybdenum, Math.floor((ship.megacredits + result.megacredits) / cost));
			result.ammo += mkt;
			result.duranium -= mkt;
			result.tritanium -= mkt;
			result.molybdenum -= mkt;
			result.megacredits -= mkt * cost;
		}
		getCargo();
		if (forTowCalculation)
			return result;

		//movement
		var x,
		y,
		dist;
		var a = vgap.getNextLoc(ship); //includes breakTow
		x = a[0],
		y = a[1],
		dist = a[2];
		var actFuel = ship.neutronium + result.neutronium;
		var actMass = hull.mass + vgap.shipScreen.getTotalCargo(ship) + result.cargo + actFuel;
		if (ship.warp > 0 && dist > 0) {
			actMass += (ship.beams > 0 ? vgap.getBeam(ship.beamid).mass * ship.beams : 0);
			actMass += (ship.torps > 0 ? vgap.getTorpedo(ship.torpedoid).mass * ship.torps : 0);
			if (ship.mission == 6 && ship.mission1target != 0 && actFuel > 0) {
				var towShip = vgap.getShip(ship.mission1target);
				var towTarget = vgap.isTowTarget(ship.id);
				if (towShip != null && (towTarget == null || towShip.id != towTarget.id)) { //towee towing the tower?
					if (towShip.ownerid == vgap.player.id || towShip.allyupdate) {
						if (!vgap.breakTow(ship, towShip)) {
							var resultTowship = this.predictor(towShip, true);
							var towMass = 0;
							towMass += vgap.getHull(towShip.hullid).mass + vgap.shipScreen.getTotalCargo(towShip) + resultTowship.cargo + towShip.neutronium + resultTowship.neutronium;
							towMass += (towShip.beams > 0 ? vgap.getBeam(towShip.beamid).mass * towShip.beams : 0);
							towMass += (towShip.torps > 0 ? vgap.getTorpedo(towShip.torpedoid).mass * towShip.torps : 0);
							actMass += 10 * Math.truncate(towMass / 10); //according to http://donovansvgap.com/help/details.htm#fuel2
						}
					} else
						actMass += 10 * Math.truncate(towShip.mass / 10);
				}
			}
			var speed = vgap.getSpeed(ship.warp, vgap.getHull(ship.hullid));
			var xv = (vgap.getEngine(ship.engineid)["warp" + ship.warp] || 0);
			var turnFuel = (vgap.isHyping(ship) || vgap.isChunnelling(ship) ? 50 : Math.floor(xv * Math.floor(actMass / 10) * ((Math.floor(dist) / speed) / 10000)));
			result.neutronium -= turnFuel;
			/* No need at Hover Quapla
			var color = "green";
			if (ship.neutronium + result.neutronium < 0 && !(vgap.isHyping(ship) || vgap.isChunnelling(ship))) { //correction for running out of fuel (experimental)
			result.neutronium = -ship.neutronium;
			var i = 0,
			f = 0;

			/*while (f<actFuel+1) {
			dist=i;
			i+=1;
			f=Math.floor(xv * Math.floor(actMass / 10) * (i / speed) / 10000);
			//console.log("dist: "+i+" fuel: "+f)
			}*/
			/*
			dist = actFuel / turnFuel * dist;
			a = vgap.getNextLoc(ship, dist);
			x = a[0],
			y = a[1],
			dist = a[2];
			color = "red";
			} */
			/* if (ship.x == x && ship.y == y)
			color = "red";
			vgap.map.drawCircle(x, y, 3,{
			stroke : color,
			"stroke-width" : 1,
			"stroke-opacity" : "1"
			}
			);  // Quapla whats that? */
		}
		this.totalmass = actMass;

		//ramscoop (cobol)
		if (hull.id == 96 && ship.warp > 0 && dist > 0) {
			result.neutronium += Math.min(Math.floor(dist) * 2, hull.fueltank - (ship.neutronium + result.neutronium));
		}

		//radiation
		var radiation = vgap.shipScreen.getPathRadiation(ship);
		var crewDeath = vgap.shipScreen.radiationEffect(ship, radiation);
		if (crewDeath > 0)
			result.crew -= Math.min(crewDeath, ship.crew + result.crew);

		//glory device
		var nextloc = vgap.getNextLoc(ship);
		var d = 0;
		for (i = 0; i < vgap.ships.length; i++) {
			var s = vgap.ships[i];
			if (s.ownerid != vgap.player.id && !s.allyupdate)
				continue;
			var nextloc1 = vgap.getNextLoc(s);
			if ((s.hullid == 39 || s.hullid == 41 || s.hullid == 1034 || s.hullid == 1039) && s.friendlycode.toUpperCase() == "POP" && nextloc[0] == nextloc1[0] && nextloc[1] == nextloc1[1]) {
				if (s.id == ship.id)
					result.damage = 100;
				var factor = 10000; //normal damage
				if (s.hullid % 1000 == 39 && s.ownerid == ship.ownerid)
					factor = 2000; //D19b, D19c (20%)
				if (s.hullid == 41 && s.ownerid == ship.ownerid)
					factor = 1000; //saber (10%)
				if (s.hullid == 1034) {
					if (s.ownerid == ship.ownerid)
						factor = 2000; //D7b (20%) 2do: "friendly ships" - whatever that is
					else
						factor = 5000; //50%
				}
				result.damage += Math.floor((factor) / (hull.mass + 1));
				d++;
			}
			if (ship.damage + result.damage > 100) {
				result.damage = 100 - ship.damage;
				break;
			};
		}

		//repair if glory
		if (d > 0 && ship.damage + result.damage > 0 && ship.damage + result.damage < 100) {
			var rep = Math.floor(ship.supplies / 5);
			result.supplies -= rep * 5;
			result.damage -= rep;
		}

		/* wait a minute, that's after movement (careful, needs to really get there!)
		var target=vgap.getPlanetAt(x,y);
		var targetStarbase=vgap.getStarbase(target.id);
		//starbase unload all freighters
		if (targetStarbase && targetStarbase.mission == 4) {
		result.duranium-=ship.duranium;
		result.tritanium-=ship.tritanium;
		result.molybdenum-=ship.molybdenum;
		result.supplies-=ship.supplies;
		result.clans-=ship.clans;
		result.megacredits-=ship.megacredits;
		}


		//starbase refuel - that means calculating fuel of all ships (with lower id with this as target
		//starbase load torps onto ships - similar here
		 */
		getCargo();
		var prediction = {};
		prediction.neutronium = result.neutronium;
		prediction.duranium = result.duranium;
		prediction.tritanium = result.tritanium;
		prediction.molybdenum = result.molybdenum;
		prediction.megacredits = result.megacredits;
		prediction.damage = result.damage;
		prediction.crew = result.crew;
		prediction.ammo = result.ammo;
		prediction.supplies = result.supplies;
		prediction.cargo = result.cargo;
		prediction.x = x;
		prediction.y = y;
		hitText.prototype.prediction = prediction;
		return result;
	};

	//Helpers for Prediction

	vgaPlanets.prototype.getNextLoc = function (ship, maxDist) { //2do? include chunnelling?
		if (!ship)
			return;
		var curX = ship.x,
		curY = ship.y;
		var tower = vgap.isTowTarget(ship.id);
		if (tower != null && !vgap.breakTow(tower, ship) && ship.mission != 6) {
			var TowerLoc = this.getNextLoc(tower);
			TowerLoc[2] = 0; //didn't travel on own engine
			return TowerLoc;
		}
		if (vgap.isChunnelling(ship)) {
			var targetId = parseInt(ship.friendlycode, 10);
			var target = vgap.getShip(targetId);
			if (!target)
				return;
			return [target.x, target.y, 0];
		}
		if (vgap.isHyping(ship) && (!maxDist || maxDist != 350)) { //catch recursion
			var hypdist = hitText.prototype.getDistQ(ship.x, ship.y, ship.targetx, ship.targety);
			if (hypdist > 360.05 || hypdist < 339.95)
				return this.getNextLoc(ship, 350);
			else
				return [ship.targetx, ship.targety, hypdist];
		}
		var endX = ship.targetx;
		var endY = ship.targety;
		if (ship.mission == 7) { //intercept
			var interceptTarget = null;
			if (ship.mission1target != 0) {
				interceptTarget = vgap.getShip(ship.mission1target);
				if (interceptTarget.ownerid == vgap.player.id || interceptTarget.allyupdate) { //only ships that can be predicted correctly
					var a = this.getNextLoc(interceptTarget);
					endX = a[0];
					endY = a[1];
				}
			}
		}
		var diffX = endX - curX;
		var diffY = endY - curY;
		if (diffX == 0 && diffY == 0)
			return [curX, curY, 0];
		var totalDist = hitText.prototype.getDistQ(curX, curY, endX, endY);
		var speed = vgap.getSpeed(ship.warp, vgap.getHull(ship.hullid));
		if ((maxDist == null || maxDist > totalDist) && !(vgap.isHyping(ship) && maxDist == 350)) { //enough fuel and not indirecthyping
			if (vgap.isHyping(ship))
				speed = 359.55;
			if (totalDist < speed + 0.5) { //will arrive this turn
				var warpPlanet = vgap.warpWell(endX, endY);
				var hypThreeAway = vgap.isHyping(ship) && ((Math.abs(warpPlanet.x - endX) == 3) || (Math.abs(warpPlanet.y - endY) == 3));
				if (warpPlanet && speed > 1 && !hypThreeAway) {
					endX = warpPlanet.x;
					endY = warpPlanet.y;
				}
				return [endX, endY, totalDist];
			} else
				totalDist = speed; //waypoint is longer than speed
		} else
			totalDist = maxDist; //not enough fuel - experimental!!

		var newX,
		newY;
		if (Math.abs(diffX) > Math.abs(diffY)) {
			var moveX = Math.floor((totalDist * diffX) / Math.sqrt((diffX * diffX) + (diffY * diffY)) + 0.5);
			var moveY = Math.floor(moveX * (diffY / diffX) + 0.5);
			newX = curX + moveX;
			newY = curY + moveY;
		} else {
			var moveY = Math.floor((totalDist * diffY) / Math.sqrt((diffX * diffX) + (diffY * diffY)) + 0.5);
			var moveX = Math.floor(moveY * (diffX / diffY) + 0.5);
			newY = curY + moveY;
			newX = curX + moveX
		}
		var actDist = Math.sqrt((moveX * moveX) + (moveY * moveY)); //actual distance travelled by own engine (for fuel calculation)
		var warpPlanet = vgap.warpWell(newX, newY);
		var hypThreeAway = vgap.isHyping(ship) && ((Math.abs(warpPlanet.x - newX) == 3) || (Math.abs(warpPlanet.y - newY) == 3));
		if (warpPlanet && speed > 1 && !hypThreeAway) {
			newX = warpPlanet.x;
			newY = warpPlanet.y;
		}
		return [newX, newY, actDist];
	};

	vgaPlanets.prototype.warpWell = function (x, y) { // returns planet or false
		for (var i = 0; i < this.planets.length; i++) {
			var planet = this.planets[i];
			if (planet.debrisdisk > 0)
				continue;
			var dist = hitText.prototype.getDistQ(x, y, planet.x, planet.y);
			if (dist <= 3 && dist > 0)
				return planet;
		}
		return false;
	};

	vgaPlanets.prototype.breakTow = function (tower, towee) {
		if (!tower || !towee)
			return;
		var towTarget = vgap.isTowTarget(towee.id)
			if (towTarget == null || tower.id != towTarget.id)
				return true; //2do: what if multiple ships tow? isTowTarget returns only the lowest id ship
			if (vgap.getHull(tower.hullid).engines == 1)
				return true;
			var f1 = ((tower.hullid == 44 || tower.hullid == 45 || tower.hullid == 46) ? 2 : 1);
		var f2 = ((towee.hullid == 44 || towee.hullid == 45 || towee.hullid == 46) ? 2 : 1);
		if (f1 * tower.warp < f2 * tower.warp && hitText.prototype.getDistQ(towee.x, towee.y, towee.targetx, towee.targety) > vgap.getSpeed(towee.warp, towee.hullid) && towee.neutronium >= 25)
			return true;
		return false;
	};

	vgaPlanets.prototype.isChunnelling = function (ship) {
		if ((ship.hullid == 56 || ship.hullid == 1055) && ship.warp == 0 && ship.neutronium >= 50 && ship.mission != 6) {
			if (this.isTowTarget(ship.id) == null) {
				var RegExPattern = /([0-9])([0-9])([0-9])/;
				var matchExpression = ship.friendlycode;
				matchExpression = matchExpression.toString();
				if ((matchExpression.match(RegExPattern)) && (matchExpression != '')) {
					var targetId = parseInt(ship.friendlycode, 10);
					var target = vgap.getShip(targetId);
					if (target != null) {
						if (target.ownerid == ship.ownerid && (target.hullid == 56 || target.hullid == 1054 || (ship.hullid == 1055 && target.hullid == 51)) && target.warp == 0 && target.neutronium >= 1 && target.mission != 6 && hitText.prototype.getDistQ(ship.x, ship.y, target.x, target.y) >= 100 && this.isTowTarget(target.id) == null)
							return true;
					}
				}
			}
		}
		return false;
	};

	// Pediction

	vgaPlanets.prototype.setupAddOn = function (addOnName) {
		if (vgaPlanets.prototype.addOns == null)
			vgaPlanets.prototype.addOns = {};
		vgaPlanets.prototype.addOns[addOnName] = {};
		var settings = localStorage.getItem(addOnName + ".settings");
		if (settings != null)
			vgaPlanets.prototype.addOns[addOnName].settings = JSON.parse(settings);
		else
			vgaPlanets.prototype.addOns[addOnName].settings = {};
		vgaPlanets.prototype.addOns[addOnName].saveSettings = function () {
			localStorage.setItem(addOnName + ".settings", JSON.stringify(vgaPlanets.prototype.addOns[addOnName].settings));
		}
	};
	vgaPlanets.prototype.setupAddOn("vgapHoverPrediction");

	/*
	if (vgaPlanets.prototype.addOns == null) vgaPlanets.prototype.addOns = {};
	vgaPlanets.prototype.addOns.vgapHoverPrediction = {};
	var settings = localStorage.getItem("vgapHoverPrediction.settings");
	if (settings != null)
	vgaPlanets.prototype.addOns.vgapHoverPrediction.settings = JSON.parse(settings);
	else
	vgaPlanets.prototype.addOns.vgapHoverPrediction.settings = {}; //{terseInfo: false};

	vgaPlanets.prototype.addOns.vgapHoverPrediction.saveSettings = function () {
	localStorage.setItem("vgapHoverPrediction.settings", JSON.stringify(vgaPlanets.prototype.addOns.vgapHoverPrediction.settings));
	};
	 */

	var old_hitTextBox = vgapMap.prototype.hitTextBox;
	vgapMap.prototype.hitTextBox = function (hit) {
		// replace completely, pretty sure i want to do this
		// oldHitTextBox.apply(this, arguments);

		var settings = vgap.addOns.vgapHoverPrediction.settings;
		var txt = "";
		var wtx = "";
		var change = 0;
		var html = '';
		if (hit.isPlanet) { //planet
			if (settings.tersePlanet) { // Show new Info
				var predclans = (hit.clans > 0 ? hit.clans : 0);
				var prednativeclans = (hit.nativeclans > 0 ? hit.nativeclans : 0);
				var predsupplies = (hit.supplies > 0 ? hit.supplies : 0);
				var predmegacredits = (hit.megacredits > 0 ? hit.megacredits : 0);
				var predduranium = (hit.duranium > 0 ? hit.duranium : 0);
				var predmolybdenum = (hit.molybdenum > 0 ? hit.molybdenum : 0);
				var predtritanium = (hit.tritanium > 0 ? hit.tritanium : 0);
				var predneutronium = (hit.neutronium > 0 ? hit.neutronium : 0);

				// if (hit.id < 0)	{	hit = vgap.getPlanet(-hit.id); } // For what is that good? Quapla
				// 8 Colomns
				// AAAA | 00000000 | + 0000 | (00000') || BBBB | 00000000 | + 0000 | (00000')
				// Cln: |    23450 | +   21 |   (451') || Avi: |    23450 | +   21 |   (451')

				txt += "<div class='ItemSelectionBox minCorrection'>";
				// txt += "<span>" + hit.id + ": " + hit.name;
				// if (hit.temp != -1)
				//	txt += "<span style='float:right;'>Temp: " + hit.temp + "</span>";
				// txt += "</span>";
				txt += "<table style='table-layout:fixed' class='CleanTable'><colgroup span='8'></colgroup>";
				if (hit.infoturn == 0) { //unknown planet
					// txt += this.hitText(hit, hit.isPlanet).replace("&nbsp", ""); // Later for all Planets
					txt += "<tr><td>" + hit.id + ": unknown</td></tr>";
				} else {
					// if (hit.nativeclans > 0) // Has natives
					// {
					//	txt += "<tr><td colspan=8>" + addCommas(hit.nativeclans * 100) + " " + hit.nativeracename + " - " + hit.nativegovernmentname + "</td></tr>";
					// }
					//txt += "<div class='ItemSelectionBox minCorrection'>";
					//txt += "<table class='CleanTable'>";
					if (hit.ownerid != vgap.player.id)
						wtx = " class='WarnText'";
					else if (hit.readystatus == 0)
						wtx = "";
					else
						wtx = " style='color:#90ee90;'"; // Planet ready, show green?
					txt += "<tr><td" + wtx + ">" + hit.id + ": </td>";
					txt += "<td colspan = '3'" + wtx + ">" + hit.name + "</td>";
					txt += "<td style='text-align:right;'>FC:&nbsp</td><td>" + hit.friendlycode + "</td>";
					if (hit.temp != -1) // Temperature known
					{
						if (hit.temp > 84 || hit.temp < 15)
							wtx = " class='WarnText'";
						else
							wtx = ""; // Planet Hot/Cold?
						txt += "<td style='text-align:right;' colspan='2'" + wtx + ">&nbsp;" + hit.temp + "°</td>";
					}
					txt += "</tr>";
					// txt += "<td>Cln:&nbsp;</td><td>" + hit.clans + "&nbsp;</td><td style='float:right;'>+ " + (minPop == 0 ? "n/a" : minPop) + "+&nbsp;</td><td style='float:right;'>(" + maxPop + ")</td>";
					if (hit.clans > 0)
						wtx = "Clans";
					else
						wtx = "unowned";
					var grows = hitText.prototype.GetPopGrowth(hit);
					var maxcln = hitText.prototype.GetsmaxPop(hit, false); // Old function: hitText.prototype.GetMaxPop(hit);
					var change = hitText.prototype.GetMinPopGrow(hit);
					if (hit.clans < change || hit.clans < 1) // too little clans to grow
						txt += "<tr>" + hitText.prototype.showMin(wtx, hit.clans, "[" + change + "]", maxcln, "");
					else
						txt += "<tr>" + hitText.prototype.showMin(wtx, hit.clans, (grows == 0 ? "n/a" : grows), maxcln, (grows < 0 ? "-" : "+"));
					if (hit.ownerId = vgap.player.id)
						predclans += grows; // Clans added
					else
						predclans = 0;

					if (hit.nativeclans > 0) // Has Natives
					{
						txt += "<td style='text-align:right;'>&nbsp" + addCommas(hit.nativeclans) + "</td>";
						txt += "<td>&nbsp" + hit.nativeracename.substr(0, 5) + "</td>";
						if (hit.ownerid == vgap.player.id) {
							if (hit.nativehappypoints < 40) {
								wtx = "ff0000"; // Red
							} else if (hit.nativehappypoints < 70) {
								wtx = "ffa500"; // Orange
							} else {
								wtx = "90ee90"; // Green
							}
						}
						txt += "<td style='color:#" + wtx + ";'>&nbsp;" + hit.nativehappypoints + "%</td>";
						txt += "<td>&nbsp;" + hit.nativetaxrate + "%</td>";
					}

					txt += "</tr>";

					// if (vgap.player.status == 7 && !hit) {
					// var e = ["None", "Colonization", "Build Starbase", "Supply
					// Starbase", "Exploration", "Build Special", "Attack", "Defend",
					// "Move Fuel"];
					// return "<tr><td colspan='" + a + "' class='WarnText'>" +
					// e[b.goal] + "-" + b.goaltarget + "</td></tr>"
					// }
					var sp = hit.factories;
					var cs = 0;
					var nt = 0;
					var cs10 = 0;
					var nt10 = 0;
					var sps = 0;
					if (hit.nativeclans > 0) {
						if (hit.nativetype == 2) { // bovinoid
							spn = Math.floor(hit.nativeclans / 100);
							sps = hit.clans - spn;
							sp += sps > 0 ? spn : hit.clans;
						}

						nt = hitText.prototype.nativeTaxAmount(hit, hit.nativetaxrate); // Can pay max
						ns = hitText.prototype.nativesupportedtax(hit); // Can get may
						cs = ns - nt; // Won't get because lack of Clans
						nt = Math.min(nt, ns);

						nt10 = hitText.prototype.nativeTaxAmount(hit, 10);
						ns10 = hitText.prototype.nativesupportedtax(hit);
						cs10 = ns10 - nt10;
						nt10 = Math.min(nt10, ns10);
					}

					ct = Math.round(hit.clans * hit.colonisttaxrate / 1000);

					mn = hitText.prototype.miningRate(hit, hit.groundneutronium, hit.densityneutronium, hit.mines);
					md = hitText.prototype.miningRate(hit, hit.groundduranium, hit.densityduranium, hit.mines);
					mm = hitText.prototype.miningRate(hit, hit.groundmolybdenum, hit.densitymolybdenum, hit.mines);
					mt = hitText.prototype.miningRate(hit, hit.groundtritanium, hit.densitytritanium, hit.mines);
    
					var nText = hit.groundneutronium;
					var dText = hit.groundduranium;
					var tText = hit.groundtritanium;
					var mText = hit.groundmolybdenum;
					if (hit.totalneutronium > 0 && hit.groundneutronium < 0) { //"total" info available, surface/ground is not, enables display of dark sense and superspy info in hover text
						nText = hit.totalneutronium;
						dText = hit.totalduranium;
						tText = hit.totaltritanium;
						mText = hit.totalmolybdenum;
					}

					if (hit.groundneutronium > 0) {
						txt += "<tr>" + hitText.prototype.showMin("Neut", hit.neutronium, mn, nText, "+");
						predneutronium += mn;

						txt += "<td style='text-align:right;'>" + addCommas(hit.supplies) + "</td><td>&nbspSupp</td>";
						txt += "<td style='text-align:right;'>&nbsp+&nbsp" + sp;
						if (sps < 0)
							txt += "</td><td class='val' style='color:#f00;'>-" + (-sps);
						txt += "</td></tr>";
						predsupplies += sp;

						txt += "<tr>" + hitText.prototype.showMin("Dura", hit.duranium, md, dText, "+");
						predduranium += md;

						txt += "<td style='text-align:right;'>" + addCommas(hit.megacredits) + "</td>";
						txt += "<td style='text-align:center;'>MC</td><td style='text-align:right;'>&nbsp+&nbsp" + (nt + ct);
						if (cs < 0)
							txt += "</td><td class='val' style='color:#f00;'>-" + (-cs);
						txt += "</td></tr>";
						predmegacredits += (nt + ct);

						txt += "<tr>" + hitText.prototype.showMin("Trit", hit.tritanium, mt, tText, "+");
						predtritanium += mt;

						txt += "<td style='text-align:right;'>" + addCommas(hit.megacredits + hit.supplies) + "</td>";
						txt += "<td style='text-align:center;'>$</td>";
						txt += "<td style='text-align:right;'>&nbsp+&nbsp" + (nt + ct + sp);
						txt += "</td></tr>";
						/* Not used					if (hit.nativeclans > 0){
						txt += "<td>&nbsp;10%:</td><td>&nbsp;</td><td>" + nt10 + "-&nbsp;";
						if (cs10 < 0)
						txt += "</td><td  class='WarnText'>" + (-cs10);
						} */
						txt += "<tr>" + hitText.prototype.showMin("Moly", hit.molybdenum, mm, mText, "+");
						predmolybdenum += mm;

						txt += "<td>&nbsp&nbspM.&nbspF.&nbspD.</td><td style='text-align:right;'>&nbsp" + hit.mines + "</td><td style='text-align:right;'>|&nbsp" + hit.factories + "</td><td style='text-align:right;'>&nbsp|&nbsp" + hit.defense + "</td></tr>";

						var sb = vgap.getStarbase(hit.id);
						if (sb != null && (hit.ownerid == vgap.player.id || vgap.fullallied(hit.ownerid))) {
							if (sb.starbasetype != 2) {
								if (sb.isbuilding) {
									txt += "<tr><td colspan='8'>Build:&nbsp;" + vgap.getHull(sb.buildhullid).name + "</td></tr>";
								} else {
									txt += "<tr><td colspan='8' class='WarnText'>Starbase is not building</td></tr>";
								}
							}
							/// Add tech levels for SB
							txt += "<tr><td colspan='2'>Defense: " + sb.defense + "</td><td colspan='2'>Fighters: " + sb.fighters + "</td>";
							txt += "<td colspan='4'>Tech: H-" + sb.hulltechlevel + " E-" + sb.enginetechlevel + " B-" + sb.beamtechlevel;
							txt += " T-" + sb.torptechlevel + "</td></tr>";
						} else {
							if (hit.duranium > 119 && hit.tritanium > 401 && hit.molybdenum > 339 && (hit.megacredits + hit.supplies) > 899)
								txt += "<tr><td colspan='8' style='color:#0f0;'>Can build Starbase</td></tr>";
						}
					}
					//known enemy planet
					if (hit.ownerid != vgap.player.id && hit.ownerid != 0) {
						var player = vgap.getPlayer(hit.ownerid);
						var race = vgap.getRace(player.raceid);
						txt += "<tr><td colspan='8' class='WarnText'>" + race.name + " (" + player.username + ")</td></tr>";
					}
					// txt += this.hitText(hit, hit.isPlanet).replace("&nbsp", "");
				} // End of known Planets
				wtx = this.hitText(hit, hit.isPlanet).replace("'4'", "'8'");
				txt += wtx.replace("&nbsp", "");
				txt += "</table></div>";

				var change = 0;
				if (settings.showShips) { // Show new Info
					var dist;
					html = "";
					for (var i = 0; i < vgap.myships.length; i++) {
						var ship = vgap.myships[i];
						hitText.prototype.predictor(ship); // Get next Ressorces
						var hull = vgap.getHull(ship.hullid);
						// var dest = vgap.getDest(ship);
						dist = Math.dist(hit.x, hit.y, hitText.prototype.prediction.x, hitText.prototype.prediction.y);
						if (dist <= 3 && dist >= 0) {
							change += 1;
							html += "<tr><td>" + ship.id + ":</td>";
							html += "<td colspan='4'>" + ship.name.substr(0, 15) + "&nbsp(" + hitText.prototype.shortHullName(hull) + ")</td>";
							html += "<td colspan='3'>" + "E-" + ship.engineid;
							if (ship.beams > 0) // Has Beams?
								html += "&nbsp" + "B-" + ship.beamid;
							if (ship.torps > 0) // Has Launchers?
								html += "&nbsp" + "T-" + ship.torpedoid + ":";
							if (ship.bays > 0) // Has Fighter-Bays?
								html += "&nbspF-" + ":";
							if (ship.bays > 0 || ship.torps > 0)
								html += "&nbsp" + ship.ammo + "</td></tr>";
							predclans += ship.clans;
							predsupplies += ship.supplies + hitText.prototype.prediction.supplies;
							predmegacredits += ship.megacredits + hitText.prototype.prediction.megacredits;
							predduranium += ship.duranium + hitText.prototype.prediction.duranium;
							predmolybdenum += ship.molybdenum + hitText.prototype.prediction.molybdenum;
							predtritanium += ship.tritanium + hitText.prototype.prediction.tritanium;
							predneutronium += ship.neutronium + hitText.prototype.prediction.neutronium;
							// more to come here

						}
					}
					if (change > 0) {
						txt += "<div class='ItemSelectionBox minCorrection'>";
						txt += "<table class='CleanTable' style='width: 100%'><colgroup span='8'></colgroup>"; // New Table
						txt += "<tr><td colspan='8'>" + change + " ships here at next turn:</td></tr>";
						txt += html;
						txt += "</table></div>";
					} // else no ships here no show
				} // else nothing

				if (settings.showRessources) { // Show next Ressources
					html = "<div class='ItemSelectionBox minCorrection'>";
					html += "<table class='CleanTable' style='width: 100%'><colgroup span='8'></colgroup>"; // New Table
					html += "<tr><td colspan='8'>Ressources here at next turn:</td></tr>";
					html += "<tr><td>&nbsp&nbspCln:</td><td style='text-align:right;'>" + addCommas(predclans) + "</td>";
					if (prednativeclans > 0) {
						html += "<td>&nbsp&nbsp" + hit.nativeracename.substr(0, 3) + ":</td><td style='text-align:right;'>" + addCommas(prednativeclans) + "</td>";
					} else {
						html += "<td colspan='2'>&nbsp</td>";
					}
					html += "<td>&nbsp&nbspSup:</td><td style='text-align:right;'>" + addCommas(predsupplies) + "</td>";
					html += "<td>&nbsp&nbsp&nbspMC:</td><td style='text-align:right;'>" + addCommas(predmegacredits) + "</td></tr>";
					html += "<tr><td>&nbsp&nbspNeu:</td><td style='text-align:right;'>" + addCommas(predneutronium) + "</td>";
					html += "<td>&nbsp&nbspDur:</td><td style='text-align:right;'>" + addCommas(predduranium) + "</td>";
					html += "<td>&nbsp&nbspTri:</td><td style='text-align:right;'>" + addCommas(predtritanium) + "</td>";
					html += "<td>&nbsp&nbspMol:</td><td style='text-align:right;'>" + addCommas(predmolybdenum) + "</td>";
					html += "</table></div>";
					txt += html;
				} // else nothing

				// Show known Enemy Ships at X/Y
				var efound = false;
				if (vgap.plugins["enemyShipListPlugin"]) { // Plugin Loaded - find that Ship in List...
					var eship;
					var ship;
					var wtx = "";
					//see if the ship exist in the list
					for (var j = 0; j < vgap.plugins["enemyShipListPlugin"].enemyShipList.length; j++) {
						eship = vgap.plugins["enemyShipListPlugin"].enemyShipList[j];
						if (eship.x == hit.x && eship.y == hit.y && eship.ownerid != (vgap.player.id || vgap.fullallied(eship.ownerid))) { // Enemy Ship at position
							efound = true;
							var eplayer = vgap.getPlayer(eship.ownerid);
							var hull = vgap.getHull(eship.hullid);
							var race = vgap.getRace(eplayer.raceid);
							if (settings.terseShip) {
								wtx += "<tr><td colspan='5' class='WarnText'>" + eship.id + ": " + eship.name.substr(0, 10) + "&nbsp(" + race.name + "'s " + hitText.prototype.shortHullName(hull) + ")</td>";
								if (vgap.game.turn <= eship.infoturn) { //ignore info from future turns in case of history
									wtx += "<td colspan='3'>" + "&nbspE-" + eship.engineid;
									if (eship.beams > 0) // Has Beams?
										wtx += "&nbsp" + "B-" + eship.beamid;
									if (eship.torps > 0) // Has Launchers?
										wtx += "&nbsp" + "T-" + eship.torpedoid + ":";
									if (hull.fighterbays > 0) // Has Fighter-Bays?
										wtx += "&nbspF-" + hull.fighterbays + ":";
									if (hull.fighterbays > 0 || eship.torps > 0)
										wtx += "&nbsp" + eship.ammo;
								} else
									wtx += "<td colspan='3'>Old info from turn: " + eship.infoturn + "</td>";
								wtx += "</td></tr>";
								wtx += "<tr><td>Heading:</td><td>&nbsp;" + gsv(eship.heading);
								wtx += "</td><td>&nbsp;at Warp:</td><td>&nbsp;" + gsv(eship.warp);
								wtx += "</td><td>&nbsp;Mass:</td><td>&nbsp;" + gsv(eship.mass);

								var cargo = eship.mass - hull.mass;

								var weappon = 0;
								if (eship.beams > 0) {
									var beam = vgap.getBeam(eship.beamid);
									weappon += beam.mass * eship.beams;
								}
								if (eship.torps > 0) {
									var torp = vgap.getTorpedo(eship.torpedoid);
									weappon += torp.mass * eship.torps;
								}
								var wwtx = "";
								if (weappon > 0)
									if (cargo < weappon)
										wwtx = "0-";
									else
										wwtx = (cargo - weappon) + "-";
								wwtx += cargo;
								wtx += "</td><td colspan='2'>&nbsp;(" + wwtx + ")</td></tr>";
							} else {
								wtx += "<tr><td colspan='2' class='BadText'>" + eship.id + ": " + eship.name + "</td></tr>";
								wtx += "<tr><td colspan='2' class='BadText'>" + hull.name + "</td></tr>";
								wtx += "<tr><td>Heading:</td><td>&nbsp;" + gsv(eship.heading) + " at Warp: " + gsv(eship.warp) + "</td></tr>";
								wtx += "<tr><td>Mass: </td><td>&nbsp;" + gsv(eship.mass) + "</td></tr>";
								wtx += "<tr><td colspan='2'>" + race.name + " (" + player.username + ")" + "</td></tr>";
								//wtx += "<tr><td>Neutronium:</td><td>?/" + hull.fueltank + " </td><td>&nbsp;Total Cargo:</td><td>?/" + hull.cargo + "</td></tr>";
							}
						}
					}
					if (efound) {
						html = "<div class='ItemSelectionBox minCorrection'>";
						html += "<table class='CleanTable' style='width: 100%'><colgroup span='8'></colgroup>";
						html += "<td colspan='8'>Known enemy ships here:</td>"
						html += wtx;
						html += "</table></div>";
						txt += html;
					}
				} // 4 Tabs End if vgap.plugins
			} else { // Call original function...
				var txt = old_hitTextBox.apply(this, arguments);
			}
		} // End of Planets 2 Tabs
		else { //ships
			if (settings.terseShip) {
				var wtx = "";
				var ship = hit;
				var hull = vgap.getHull(ship.hullid);
				var totalCargo = ship.ammo + ship.duranium + ship.tritanium + ship.molybdenum + ship.supplies + ship.clans;
				if (ship.ownerid == vgap.player.id || vgap.fullallied(ship.ownerid)) {
					html = "<div class='ItemSelectionBox minCorrection'>";
					var player = vgap.getPlayer(ship.ownerid);
					var race = vgap.getRace(player.raceid);
					html += "<table class='CleanTable' style='width: 100%'>"; // New Table
					if (hit.readystatus == 0) // Why check this? hit.ownerid == vgap.player.id
						wtx = "";
					else
						wtx = " style='color:#90ee90;'"; // Ship ready, show green?
					if ((settings.showHullForAllies && vgap.fullallied(ship.ownerid)) || (settings.showHullForMine && ship.ownerid == vgap.player.id)) {
						html += "<tr><td colspan='5'" + wtx + ">" + ship.id + ": " + ship.name.substr(0, 15) + "&nbsp(" + hitText.prototype.shortHullName(hull) + ")</td>";
						html += "<td colspan='3'>" + "&nbspE-" + ship.engineid;
						if (ship.beams > 0) // Has Beams?
							html += "&nbsp" + "B-" + ship.beamid;
						if (ship.torps > 0) // Has Launchers?
							html += "&nbsp" + "T-" + ship.torpedoid + ":";
						if (ship.bays > 0) // Has Fighter-Bays?
							html += "&nbspF-" + ":";
						if (ship.bays > 0 || ship.torps > 0)
							html += "&nbsp" + ship.ammo;
					} else
						html += "<tr><td colspan='8'" + wtx + ">" + ship.id + ": " + ship.name;
					html += "</td></tr>";
					if (!settings.veryterseship) {
						html += "<tr><td>Neu:</td><td>&nbsp;" + gsv(ship.neutronium) + " / " + hull.fueltank + " </td><td>&nbsp;&nbsp;&nbsp;Dur:</td><td>&nbsp;" + gsv(ship.duranium) + "</td><td>&nbsp;&nbsp;&nbsp;Tri:</td><td>&nbsp;" + gsv(ship.tritanium) + "</td><td>&nbsp;&nbsp;&nbsp;Mol:</td><td>&nbsp;" + gsv(ship.molybdenum) + "</td></tr>";
						html += "<tr><td>MC:</td><td>&nbsp;" + gsv(ship.megacredits) + "</td><td>&nbsp;&nbsp;&nbspCln:</td><td>&nbsp;" + gsv(ship.clans) + "</td><td>&nbsp;&nbsp;&nbspSup:</td><td>&nbsp;" + gsv(ship.supplies) + "</td>";
						if (ship.torps > 0 || ship.bays > 0) {
							var ammoText = "&nbsp&nbsp&nbsp;Ftr";
							if (ship.torps > 0)
								ammoText = "&nbsp&nbsp&nbsp;Tor";
							html += "<td>" + ammoText + ":</td><td>&nbsp;" + gsv(ship.ammo) + "</td></tr>";
						}
					} else { // Very Terse
						html += "<tr><td>N:&nbsp;" + gsv(ship.neutronium) + "</td><td>&nbsp;D:&nbsp;" + gsv(ship.duranium) + "</td><td>&nbsp;T:&nbsp;" + gsv(ship.tritanium) + "</td><td>&nbsp;M:&nbsp;" + gsv(ship.molybdenum) + "</td>";
						html += "<td>$:&nbsp;" + gsv(ship.megacredits) + "</td><td>&nbspC:&nbsp;" + gsv(ship.clans) + "</td><td>&nbspS:&nbsp;" + gsv(ship.supplies) + "</td>";
						if (ship.torps > 0 || ship.bays > 0) {
							var ammoText = "<td>&nbsp;F:&nbsp";
							if (ship.torps > 0)
								ammoText = "<td>&nbsp;T:&nbsp";
							html += ammoText + gsv(ship.ammo) + "</td></tr>";
						}
					}
					if (ship.ownerid == vgap.player.id || ship.allyupdate) {
						html += "<tr>";
						if (settings.showShipMission)
							html += "<td colspan='2'>" + vgap.getShipMission(ship) + ((ship.mission == 6 || ship.mission == 7) && ship.mission1target > 0 ? " " + ship.mission1target : "") + "</td>";
						else
							html += "<td/><td/>";
						if (ship.damage > 0)
							html += "<td>&nbsp;&nbsp;&nbsp;Dmg:</td><td class='BadText'>&nbsp;" + ship.damage + "%</td>";
						else if (ship.iscloaked)
							html += "<td colspan='2' class='GoodText'>&nbsp;&nbsp;&nbsp;Cloaked</td>";
						else
							html += "<td/><td/>";
						html += "<td colspan='2'>&nbsp;&nbsp;&nbsp;Warp " + ship.warp + "</td>"
						html += "<td>&nbsp;&nbsp;&nbsp;FC:</td><td>&nbsp;" + ship.friendlycode + "</td></tr>";
					}
					if (settings.showPlayerForAllies && vgap.fullallied(ship.ownerid)) {
						html += "<tr><td colspan='8'>" + race.name + " (" + player.username + ")" + "</td></tr>";
					}
					html += this.hitText(hit, hit.isPlanet).replace("&nbsp", "");
					html += "</table></div>";
				} else { //enemy
					if (vgap.plugins["enemyShipListPlugin"] && (vgap.planetAt(hit.x, hit.y))) { // Plugin Loaded & no Planet - find that Ship in List...
					}
					// Nothing to do - ships already shown
					else {
						html = "<div class='ItemSelectionBox minCorrection'>";
						var player = vgap.getPlayer(ship.ownerid);
						var hull = vgap.getHull(ship.hullid);
						var race = vgap.getRace(player.raceid);
						var efound = false;
						if (vgap.plugins["enemyShipListPlugin"]) { // Plugin Loaded & no Planet - find that Ship in List...
							var eship = "";
							//see if the ship exist in the list
							for (var j = 0; j < vgap.plugins["enemyShipListPlugin"].enemyShipList.length; j++) {
								eship = vgap.plugins["enemyShipListPlugin"].enemyShipList[j];
								if (eship.id == ship.id) { // Ship in List!
									//console.log("Ship in List: ID:-"+" j:"+j+" Ship-ID:"+ship.id+" eship-ID:"+eship.id+" Beams:"+eship.beams+" ID:"+eship.beamid);
									//ship = vgap.plugins["enemyShipListPlugin"].enemyShipList[j];
									efound = true;
									break;
								}
							}
							//}
						}
						// class='enemyShipStyle'
						html += "<table class='CleanTable' style='width: 100%'><colgroup span='8'></colgroup>";
						if (settings.terseShip) {
							html += "<tr><td colspan='5' class='WarnText'>" + ship.id + ": " + ship.name.substr(0, 10) + "&nbsp(" + race.name + "'s " + hitText.prototype.shortHullName(hull) + ")</td>";
							if (efound) {
								if (vgap.game.turn <= eship.infoturn) { //ignore info from future turns in case of history

									html += "<td colspan='3'>" + "&nbspE-" + eship.engineid;
									if (eship.beams > 0) // Has Beams?
										html += "&nbsp" + "B-" + eship.beamid;
									if (eship.torps > 0) // Has Launchers?
										html += "&nbsp" + "T-" + eship.torpedoid + ":";
									if (hull.fighterbays > 0) // Has Fighter-Bays?
										html += "&nbspF-" + hull.fighterbays + ":";
									if (hull.fighterbays > 0 || eship.torps > 0)
										html += "&nbsp" + eship.ammo;
								} else
									html += "<td colspan='3'>Old info from turn: " + eship.infoturn + "</td>";
							}
							html += "</td></tr>";
							html += "<tr><td>Heading:</td><td>&nbsp;" + gsv(ship.heading);
							html += "</td><td>&nbsp;at Warp:</td><td>&nbsp;" + gsv(ship.warp);
							html += "</td><td>&nbsp;Mass:</td><td>&nbsp;" + gsv(ship.mass);
							var cargo = ship.mass - hull.mass;
							if (efound) {
								var weappon = 0;
								if (eship.beams > 0) {
									var beam = vgap.getBeam(eship.beamid);
									weappon += beam.mass * eship.beams;
								}
								if (eship.torps > 0) {
									var torp = vgap.getTorpedo(eship.torpedoid);
									weappon += torp.mass * eship.torps;
								}
								var wtx = "";
								if (weappon > 0)
									if (cargo < weappon)
										wtx = "0-";
									else
										wtx = (cargo - weappon) + "-";
							}
							wtx += cargo;
							html += "</td><td colspan='2'>&nbsp;(" + wtx + ")</td></tr>";
						} else {
							html += "<tr><td colspan='2' class='BadText'>" + ship.id + ": " + ship.name + "</td></tr>";
							html += "<tr><td colspan='2' class='BadText'>" + hull.name + "</td></tr>";
							html += "<tr><td>Heading:</td><td>&nbsp;" + gsv(ship.heading) + " at Warp: " + gsv(ship.warp) + "</td></tr>";
							html += "<tr><td>Mass: </td><td>&nbsp;" + gsv(ship.mass) + "</td></tr>";
							html += "<tr><td colspan='2'>" + race.name + " (" + player.username + ")" + "</td></tr>";
							//html += "<tr><td>Neutronium:</td><td>?/" + hull.fueltank + " </td><td>&nbsp;Total Cargo:</td><td>?/" + hull.cargo + "</td></tr>";
						}
						html += this.hitText(hit, hit.isPlanet).replace("&nbsp", "");
						html += "</table></div>";
					}
				}
				txt = html;
			} else { // Use original ship...
				var txt = old_hitTextBox.apply(this, arguments);
			}
		}
		return txt;
	};

	vgaPlanets.prototype.shipTransferView = function (ship, onclick) {
		var hull = vgap.getHull(ship.hullid);
		var totalCargo = ship.ammo + ship.duranium + ship.tritanium + ship.molybdenum + ship.supplies + ship.clans;
		var html = "<div class='ItemSelection' onclick='" + onclick + "'>";
		html += "<img src='" + hullImg(ship.hullid) + "'/>";
		if (ship.ownerid == vgap.player.id || vgap.fullallied(ship.ownerid)) {
			html += "<div  " + (vgap.fullallied(ship.ownerid) ? "class='AllyText'" : "") + ">";
			if (ship.ownerid != vgap.player.id)
				html += vgap.raceName(ship.ownerid);
			html += "<span>" + ship.id + ": " + ship.name + "</span>";
			html += "<table class='CleanTable'>";
			html += "<tr><td>Neutronium:</td><td>" + gsv(ship.neutronium) + "/" + hull.fueltank + " </td><td>Total Cargo:</td><td>" + gsv(totalCargo) + "/" + hull.cargo + "</td></tr>";
			html += "<tr><td>Duranium:</td><td>" + gsv(ship.duranium) + "</td><td>Supplies:</td><td>" + gsv(ship.supplies) + "</td></tr>";
			html += "<tr><td>Tritanium:</td><td>" + gsv(ship.tritanium) + "</td><td>Megacredits:</td><td>" + gsv(ship.megacredits) + "</td></tr>";
			html += "<tr><td>Molybdenum:</td><td>" + gsv(ship.molybdenum) + "</td><td>Clans:</td><td>" + gsv(ship.clans) + "</td></tr>";
			if (ship.torps > 0 || ship.bays > 0) {
				var ammoText = "Fighters";
				if (ship.torps > 0)
					ammoText = "Torpedos";
				html += "<tr><td>" + ammoText + ":</td><td>" + gsv(ship.ammo) + "</td></tr>";
			} else
				html += "<tr><td/><td/></tr>";
			html += "</table></div>";
		} else {
			html += "<span class='BadText'>" + ship.id + ": " + ship.name + "</span>";
			html += "<div class='BadText'>" + vgap.raceName(ship.ownerid);
			html += "<table class='CleanTable'>";
			html += "<tr><td>Neutronium:</td><td>?/" + hull.fueltank + " </td><td>Total Cargo:</td><td>?/" + hull.cargo + "</td></tr>";
			html += "</table></div>";
		}
		html += "</div>";

		// vgap.action added for the assistant (Alex):
		// vgap.action();

		return html;
	};

	vgaPlanets.prototype.shipFullInfoView = function (ship, onclick) {
		var view = this.shipTransferView(ship, onclick);
		var html = ""; //"<table class='CleanTable'>";
		//html += "<tr>";
		html += "<td>Friendly Code:</td><td>" + ship.friendlycode + "</td></tr>";
		html += "<tr><td colspan='2'>Warp " + ship.warp + "</td>"
		html += "<td colspan='2'>" + vgap.getShipMission(ship) + ((ship.mission == 6 || ship.mission == 7) && ship.mission1target > 0 ? " " + ship.mission1target : "") + "</td></tr>";
		html += "<tr>";
		if (ship.damage > 0)
			html += "<td>Damage:</td><td class='BadText'>" + ship.damage + "</td>";
		else if (ship.iscloaked)
			html += "<td colspan='2' class='GoodText'>Cloaked</td>";
		else
			html += "<td/><td/>";
		html += "</tr></table>";
		//html += "</table>"

		// vgap.action added for the assistant (Alex):
		// vgap.action();

		view = view.split("</tr></table>").join(html);
		return view;

	};

	vgaPlanets.prototype.showHover = function (shipId) {
		var ship = vgap.getShip(shipId);
		var newheight = 100;
		if (ship.ownerid == vgap.player.id || ship.allyupdate) {
			this.hc.html(this.shipFullInfoView(ship, ""));
			newheight = 120;
			if (ship.allyupdate)
				newheight += 10;
		} else if (vgap.fullallied(ship.ownerid)) {
			this.hc.html(this.shipTransferView(ship, ""));
			newheight = 110
		} else
			this.hc.html(this.shipScan(ship, "")); //Quapla check
		this.hc.show();
		this.hc.height(newheight);

		// vgap.action added for the assistant (Alex):
		//   vgap.action();

	};
	//*/

	vgaPlanets.prototype.getShipMission = function (ship) {
		var missions = new Array();
		var mdesc = new Array();
		var raceid = vgap.getPlayer(ship.ownerid).raceid;
		missions.push("Exploration");
		mdesc.push("Return information about planets you visit.");
		missions.push("Mine Sweep");
		mdesc.push("Sweep or detect enemy minefields.");
		if (ship.torps > 0) {
			missions.push("Lay Mines");
			mdesc.push("Convert your torpedos to deep space mines.");
		} else {
			missions.push("");
			mdesc.push("");
		}
		missions.push("Kill!!");
		mdesc.push("Attack any enemy ship or planet you encounter.");
		if (ship.hullid == 84 || ship.hullid == 96 || ship.hullid == 9) {
			missions.push("Bio Scan");
			mdesc.push("Search for native life on nearby planets.");
		} else {
			missions.push("Sensor Sweep");
			mdesc.push("Search for enemy colonies on nearby planets.");
		}
		missions.push("Land and Disassemble");
		mdesc.push("Dismantle this ship on an owned or unowned planet.");
		//if (ships.length > 1 && this.hull.engines > 1) {
		missions.push("Try to Tow");
		mdesc.push("Try to tow another ship at this location.");
		/*
		}
		else {
		missions.push("");
		mdesc.push("");
		}
		 */
		missions.push("Try to Intercept");
		mdesc.push("Try to intercept the ship you have selected.");
		if (raceid == 1) {
			missions.push("Super Refit");
			mdesc.push("Upgrade this ship to the best available parts. Must be at a starbase to work.");
		} else if (raceid == 2) {
			if (ship.beams > 0) {
				missions.push("Hisssss!");
				mdesc.push("Increase the happiness on the planet you orbit.");
			} else {
				missions.push("");
				mdesc.push("");
			}
		} else if (raceid == 3) {
			missions.push("Super Spy");
			mdesc.push("Spy on an enemy planet for info or to change its friendly code.");
		} else if (raceid == 4) {
			if (ship.beams > 0) {
				missions.push("Pillage Planet");
				mdesc.push("Pillage a planet for supplies and money.");
			} else {
				missions.push("");
				mdesc.push("");
			}
		} else if (raceid == 5) {
			missions.push("Rob Ship");
			mdesc.push("Rob an enemy ship of its fuel or cargo.");
		} else if (raceid == 6) {
			missions.push("Self Repair");
			mdesc.push("Repair this ship by 10% / turn.");
		} else if (raceid == 7) {
			if (ship.torps > 0) {
				missions.push("Lay Web Mines");
				mdesc.push("Convert your torpedos to special fuel sucking mines.");
			} else {
				missions.push("");
				mdesc.push("");
			}
		} else if (raceid == 8) {
			missions.push("Dark Sense");
			mdesc.push("Sense enemy colonies and starbases on nearby planets.");
		} else if (raceid == 9 || raceid == 11) {
			if (ship.bays > 0) {
				missions.push("Build Fighters");
				mdesc.push("Build fighters on your ship for 3 tritanium, 2 molybdenum and 5 supplies each.");
			} else {
				missions.push("");
				mdesc.push("");
			}
		} else if (raceid == 10) {
			missions.push("Rebel Ground Attack");
			mdesc.push("Sabotage the planet to destroy buildings and kill colonists.");
		}

		if (vgap.getHull(ship.hullid).cancloak) {
			missions.push("Cloak");
			mdesc.push("Make this ship invisible to enemies.");
		} else {
			missions.push("");
			mdesc.push("");
		}
		/*
		if (this.planet != null) {
		missions.push("Beam up Neutronium Fuel from " + this.planet.name);
		mdesc.push("");
		missions.push("Beam up Duranium from " + this.planet.name);
		mdesc.push("");
		missions.push("Beam up Tritanium from " + this.planet.name);
		mdesc.push("");
		missions.push("Beam up Molybdenum from " + this.planet.name);
		mdesc.push("");
		missions.push("Beam up Supplies from " + this.planet.name);
		mdesc.push("");
		} else {
		 */
		missions.push("Beam up Fuel");
		mdesc.push("");
		missions.push("Beam up Duranium");
		mdesc.push("");
		missions.push("Beam up Tritanium");
		mdesc.push("");
		missions.push("Beam up Molybdenum");
		mdesc.push("");
		missions.push("Beam up Supplies");
		mdesc.push("");
		//}
		return missions[ship.mission];
	};

	var old_showSettings = vgapDashboard.prototype.showSettings;
	vgapDashboard.prototype.showSettings = function () {

		old_showSettings.apply(this, arguments);

		var settings = vgaPlanets.prototype.addOns.vgapHoverPrediction.settings;

		var html = "";
		html += "<div id='vgapHoverPredictionSettings'><table>";
		html += "<tr><th colspan='4'>Add-On Settings: Quapla's Hover Prediction</th></tr>";
		html += "<tr>";
		html += "<td>Use terse planet prediction</td><td><input type='checkbox'" + (settings.tersePlanet ? "checked='true'" : "") + "onChange='vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.tersePlanet = !vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.tersePlanet; vgap.addOns.vgapHoverPrediction.saveSettings();'/></td>";
		html += "<td>Use terse ship prediction</td><td><input type='checkbox'" + (settings.terseShip ? "checked='true'" : "") + "onChange='vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.terseShip = !vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.terseShip; vgap.addOns.vgapHoverPrediction.saveSettings();'/></td>";
		html += "<td>Use very terse ship prediction</td><td><input type='checkbox'" + (settings.veryterseship ? "checked='true'" : "") + "onChange='vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.veryterseship = !vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.veryterseship; vgap.addOns.vgapHoverPrediction.saveSettings();'/></td>";
		html += "</tr><tr>";
		html += "<td>Show next ship prediction</td><td><input type='checkbox'" + (settings.showShips ? "checked='true'" : "") + "onChange='vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showShips = !vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showShips; vgap.addOns.vgapHoverPrediction.saveSettings();'/></td>";
		html += "<td>Show next Ressources prediction</td><td><input type='checkbox'" + (settings.showRessources ? "checked='true'" : "") + "onChange='vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showRessources = !vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showRessources; vgap.addOns.vgapHoverPrediction.saveSettings();'/></td>";
		html += "</tr><tr>";
		html += "<td>Show player for allied ships</td><td><input type='checkbox'" + (settings.showPlayerForAllies ? "checked='true'" : "") + "onChange='vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showPlayerForAllies = !vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showPlayerForAllies; vgap.addOns.vgapHoverPrediction.saveSettings();'/></td>";
		html += "<td>Show hull type for allied ships</td><td><input type='checkbox'" + (settings.showHullForAllies ? "checked='true'" : "") + "onChange='vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showHullForAllies = !vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showHullForAllies; vgap.addOns.vgapHoverPrediction.saveSettings();'/></td>";
		html += "</tr><tr>";
		html += "<td>Show hull type for my ships</td><td><input type='checkbox'" + (settings.showHullForMine ? "checked='true'" : "") + "onChange='vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showHullForMine = !vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showHullForMine; vgap.addOns.vgapHoverPrediction.saveSettings();'/></td>";
		html += "<td>Show mission for ships</td><td><input type='checkbox'" + (settings.showShipMission ? "checked='true'" : "") + "onChange='vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showShipMission = !vgaPlanets.prototype.addOns.vgapHoverPrediction.settings.showShipMission; vgap.addOns.vgapHoverPrediction.saveSettings();'/></td>";
		html += "</tr>";
		html += "</table></div>";

		$("#HoverSettings").after(html);
		this.pane.jScrollPane();

	};
	/* //REPLACED MAP TOOL WITH PERSISTENT SETTING
	var old_loadControls = vgapMap.prototype.loadControls;
	vgapMap.prototype.loadControls = function () {

	old_loadControls.apply(this, arguments);

	var additem = "<li onclick='vgap.addOns.vgapHoverPrediction.settings.terseInfo = !vgap.addOns.vgapHoverPrediction.settings.terseInfo;'>Switch Info View</li>";

	//$("#MapTools").append(additem);
	$("#MapTools > li:contains('Connections (q)')").after(additem);

	var height = this.controls.height() - this.toolsMenu.height();
	this.controls.css("marginTop", "-" + this.controls.height() + "px");

	};
	 */

}

var script = document.createElement("script");
script.type = "application/javascript";
script.textContent = "(" + wrapper + ")();";

document.body.appendChild(script);