This repository has been archived on 2024-07-18. You can view files and clone it, but cannot push or open issues or pull requests.
lwb5/site/static/beta5/js/pg_fleets.js

2704 lines
62 KiB
JavaScript

var autoUpdate, autoLock, onMainPage = false;
var allies, fleets, locations, players, myself;
var fAutoId = 0;
var listLocations, listMode, fDispMode, alliesMode;
var sType, sText;
var ppList, apList, opList, mfList, wfList;
var fSel, fDisp, splitParam;
var orderFleets, moveTo, moveToLoc, orderMode, waitTime, selCanHS, guessOrders, gDest, gWait, sMovex, sMovey;
var dMapX, dMapY, newDest, map, loadingMap = false, readingMoveLocation = false;
var mapCType, mapParm;
var trajectories, lTraj, trajLock;
var fleetTrajectory, sales;
var mapRemember = false;
var mFleetSelectable, mFleetSelected;
var wFleetSelectable, wFleetSelected;
function Ally(id, isMe, fSpace, gSpace, cHaul, bHaul, gaPop, canSell)
{
this.id = id;
this.isMe = isMe;
this.gSpace = gSpace;
this.fSpace = fSpace;
this.cHaul = cHaul;
this.bHaul = bHaul;
this.gaPop = gaPop;
this.canSell = canSell;
this.getName = Ally_getName;
this.planets = new Array();
this.fleets = new Array();
this.gasAt = new Hashtable();
if (isMe)
myself = this;
}
function Ally_getName()
{
return players.get(this.id);
}
function Fleet(id, owner, gaships, fighters, cruisers, bcruisers, power, mode, upkeep, name)
{
this.id = (id == "" ? ("a" + (++fAutoId)) : id);
this.owner = owner;
this.ships = [gaships,fighters,cruisers,bcruisers];
this.power = power;
this.upkeep = upkeep;
this.mode = mode;
this.name = name;
this.selected = false;
this.orders = null;
}
function FLocation(id, canMove)
{
this.oType = 0;
this.locId = id;
this.loc = null;
this.canMove = canMove;
}
function FMove(to, from, now, eta, hs, reroute)
{
this.oType = 1;
this.fromId = from; this.from = null;
this.toId = to; this.to = null;
this.curId = now; this.cur = null;
this.eta = eta; this.wait = null;
this.hyperspace = (hs == '1');
this.reroute = parseInt(reroute,10);
}
function FWait(loc, from, left, spent, minLoss, maxLoss)
{
this.oType = 2;
this.fromId = from; this.from = null;
this.locId = loc; this.loc = null;
this.spent = spent; this.left = left;
this.minLoss = minLoss; this.maxLoss = maxLoss;
}
function FOnSale(loc, sale, ib)
{
this.oType = 3;
this.locId = loc; this.loc = null;
this.saleId = sale;
this.inBundle = (ib == 1);
}
function FSold(loc, sale, soldTo, timeLeft, ib)
{
this.oType = 4;
this.locId = loc; this.loc = null;
this.soldTo = soldTo; this.timeLeft = timeLeft;
this.saleId = sale;
this.inBundle = (ib == 1);
}
function FleetLocation(id, opacity, x, y, orbit, name)
{
this.id = id;
this.opacity = opacity;
this.x = x;
this.y = y;
this.orbit = orbit;
this.name = name;
this.fleets = new Array();
this.details = null;
this.updateSelection = function () {
var e = document.getElementById('fsel-p-' + this.id);
if (!e) {
return;
}
if (this.selectableFleets == 0) {
e.innerHTML = ' ';
return;
}
e.innerHTML = '<input type="checkbox" name="psel-all-' + this.id + '" id="psel-all-' + this.id
+ '" onclick="locations.get(' + this.id + ').selectAll();"'
+ (this.selectableFleets == this.selectedFleets ? ' checked="checked"' : '')
+ ' />';
};
this.selectAll = function () {
if (autoLock) {
setTimeout('locations.get(' + this.id + ').selectAll()', 500);
return;
}
autoLock = true;
if (this.selectableFleets == 0) {
autoLock = false;
return;
}
for (var i in this.fleets) {
var e = document.getElementById('fsel' + this.fleets[i].id);
if (!e) {
continue;
}
e.checked = this.fleets[i].selected = !(this.selectableFleets == this.selectedFleets);
}
if (this.selectableFleets == this.selectedFleets) {
this.selectedFleets = 0;
} else {
this.selectedFleets = this.selectableFleets;
}
updateActions();
autoLock = false;
};
}
function PlanetDetails(owner, turrets, tPower, pop, vacation, protection, tag) {
this.owner = owner;
this.turrets = turrets;
this.tPower = tPower;
this.pop = pop;
this.vacation = (vacation == 1);
this.protection = (protection == 1);
this.tag = tag;
}
function FilteredLocation(id)
{
this.id = id;
this.fleetLocation = locations.get(id);
this.fleets = new Array();
}
function MapSystem(x, y, opacity, prot) {
this.x = x;
this.y = y;
this.opacity = opacity;
this.protection = prot;
this.locations = new Array();
}
function MapLocation(id, x, y, orbit, opacity, ally, name)
{
this.id = id;
this.x = x;
this.y = y;
this.orbit = orbit;
this.color = parseInt(opacity, 10);
if (this.color != 0)
this.color += 2;
else
this.color = parseInt(ally);
this.name = name;
}
function WayPoint(x, y, orbit, eta, name)
{
this.name = name;
this.coords = "(" + x + "," + y + "," + orbit + ")";
this.eta = eta;
}
function FleetTrajectory(fid, from, to, changed, left, hs, wait)
{
this.fleetId = fid;
this.fleet = fleets.get(fid);
this.from = from;
this.to = to;
this.changed = parseInt(changed,10);
this.left = parseInt(left,10);
this.hyperspace = (hs == '1');
this.wait = parseInt(wait,10);
this.waypoints = new Array();
}
function FleetWayPoint(id, eta, sys, orb, op, name)
{
this.id = id;
this.eta = parseInt(eta,10);
this.system = sys;
this.orbit = orb;
this.opacity = op;
this.name = name;
}
function FleetSale(loc)
{
this.id = loc;
this.fleetLocation = locations.get(loc);
this.mode = 0;
this.player = '';
this.price = 0;
this.priceText = '';
this.expires = 0;
this.isValid = false;
this.error = -1;
this.fleets = new Array();
this.drawForm = FleetSale_drawForm;
this.update = FleetSale_update;
this.validate = FleetSale_validate;
this.setMode = FleetSale_setMode;
this.setExpire = FleetSale_setExpire;
}
function FleetSale_setMode(m)
{
this.mode = m;
this.update();
this.validate();
}
function FleetSale_setExpire(x)
{
this.expires = x;
this.validate();
}
function FleetSale_update()
{
var id = 's' + this.id, c0 = 'sales.get('+this.id+').validate();return true', code = ' onChange="'+c0+'" onKeyUp="'+c0+'" onClick="'+c0+'" ';;
switch (this.mode)
{
case 0:
if (document.getElementById(id+'price'))
document.getElementById(id+'pril').innerHTML = document.getElementById(id+'pri').innerHTML = '&nbsp;';
if (!document.getElementById(id+'target'))
{
document.getElementById(id+'tar').innerHTML = '<input type="text" name="'+id+'target" id="'+id+'target"'+code+' />';
document.getElementById(id+'tarl').innerHTML = '<label for="'+id+'target">' + salesText[0] + '</label>';
}
document.getElementById(id+'target').value = this.player;
break;
case 1:
if (!document.getElementById(id+'price'))
document.getElementById(id+'pri').innerHTML = '<input type="text" name="'+id+'price" id="'+id+'price"'+code+' />';
if (!document.getElementById(id+'target'))
{
document.getElementById(id+'tar').innerHTML = '<input type="text" name="'+id+'target" id="'+id+'target"'+code+' />';
document.getElementById(id+'tarl').innerHTML = '<label for="'+id+'target">' + salesText[0] + '</label>';
}
document.getElementById(id+'pril').innerHTML = '<label for="'+id+'price">' + salesText[1] + '</label>';
document.getElementById(id+'target').value = this.player;
document.getElementById(id+'price').value = this.priceText;
break;
case 2:
case 3:
if (!document.getElementById(id+'price'))
document.getElementById(id+'pri').innerHTML = '<input type="text" name="'+id+'price" id="'+id+'price"'+code+' />';
if (document.getElementById(id+'target'))
document.getElementById(id+'tar').innerHTML = document.getElementById(id+'tarl').innerHTML = '&nbsp;';
document.getElementById(id+'pril').innerHTML = '<label for="'+id+'price">' + salesText[this.mode-1] + '</label>';
document.getElementById(id+'price').value = this.priceText;
break;
}
}
function FleetSale_validate()
{
this.isValid = false;
this.error = -1;
if (document.getElementById('s'+this.id+'target'))
this.player = document.getElementById('s'+this.id+'target').value;
if (document.getElementById('s'+this.id+'price'))
{
this.priceText = document.getElementById('s'+this.id+'price').value;
this.price = parseInt(this.priceText, 10);
}
if (this.mode < 2 && this.player == '')
{
this.error = 1;
drawSellLinks(false);
return;
}
if (this.mode != 0 && (isNaN(this.price) || this.price <= 0))
{
this.error = 2;
drawSellLinks(false);
return;
}
if (this.mode == 3 && this.expires == 0)
{
this.error = 3;
drawSellLinks(false);
return;
}
this.isValid = true;
checkAllSales();
}
function getTrajectory(fleet, to)
{
var fLoc = (fleet.orders.oType != 1 ? fleet.orders.loc : fleet.orders.cur);
var key = fLoc.id + ';' + ((fleet.ships[2] != 0 || (fleet.ships[2] == 0 && fleet.ships[3] == 0)) ? 1 : 0) + ';' + fleet.owner + ';' + to.id;
if (trajectories.containsKey(key))
return trajectories.get(key);
if (('#' + lTraj.join('#') + '#').indexOf('#' + key + '#') == -1)
{
lTraj.push(key);
x_getTrajectory(key, gotTrajectory);
}
return null;
}
function gotTrajectory(data)
{
if (data == "")
return;
while (trajLock);
trajLock = true;
var l = data.split('\n');
var t = new Array(), key = l.shift(), a, w, eta = 0;
while (l.length)
{
a = l.shift().split('#');
w = new WayPoint(a.shift(), a.shift(), a.shift(), (eta += parseInt(a.shift(), 10)), a.join('#'));
t.push(w);
}
trajectories.put(key, t);
t = new Array();
for (a=0;a<lTraj.length;a++)
if (lTraj[a] != key)
t.push(lTraj[a]);
lTraj = t;
trajLock = false;
updateTrajectories();
}
function initFleets()
{
fSel = new Array();
trajectories = new Hashtable();
lTraj = new Array();
var e = document.getElementById('finit');
if (!e)
return;
e = e.innerHTML;
var pm;
if (e.charAt(0) == '-')
{
pm = "parseMainData";
e = e.substr(2, e.length - 2);
}
else
{
var i = 0, s = '';
while (e.charAt(i) != ' ')
{
s += e.charAt(i);
i++;
}
i ++;
e = e.substr(i, e.length - i);
moveTo = parseInt(s, 10);
pm = "parseMainDataMove";
}
map = new Hashtable();
if (e.indexOf('\n') == -1) {
eval("x_getFleetsList("+pm+")");
} else {
eval(pm+"(e)");
}
}
function parseAllies(l, nAllies)
{
var i, a, o;
allies = new Hashtable();
for (i=0;i<nAllies;i++)
{
a = l.shift().split('#');
o = new Ally(a.shift(), (a.shift() == '1'), a.shift(), a.shift(), a.shift(), a.shift(), a.shift(), (a.shift() == '0'));
allies.put(o.id, o);
}
}
function parseFleets(l, nFleets)
{
var i, a, o, fs = '#' + fSel.join('#') + '#';
fleets = new Hashtable();
var p = new Array();
for (i=0;i<nFleets;i++)
{
a = l.shift().split('#');
o = new Fleet(a.shift(), a.shift(), a.shift(), a.shift(), a.shift(), a.shift(), a.shift(), a.shift(), a.shift(), a.join('#'));
p.push(o.owner);
a = l.shift().split('#');
if (o.mode < 2)
o.orders = new FLocation(a[0],a[1]);
else if (o.mode == 2)
{
o.orders = new FMove(a[0],a[1],a[2],a[4],a[5],a[6]);
if (a[3] == 2)
{
a = l.shift().split('#');
o.orders.wait = new FWait(a[0],a[1],a[2],a[3],a[4],a[5]);
o.mode = a[6];
}
else
o.mode = a[3];
}
else if (o.mode == 3)
{
o.orders = new FWait(a[0],a[1],a[2],a[3],a[4],a[5]);
o.mode = a[6];
}
else if (o.mode == 4)
{
o.orders = new FOnSale(a[0], a[1], a[2]);
o.mode = 0;
}
else if (o.mode == 5)
{
o.orders = new FSold(a[0], a[1], a[2], a[3], a[4]);
o.mode = 0;
}
o.selected = (fs.indexOf('#'+o.id+'#') != -1);
fleets.put(o.id, o);
}
return p;
}
function parsePlanets(l, nPlanets, pl) {
var i, a, b, o;
locations = new Hashtable();
for (i=0;i<nPlanets;i++) {
a = l.shift().split('#');
o = new FleetLocation(a.shift(),a.shift(),a.shift(),a.shift(),a.shift(),a.join('#'));
if (o.opacity == 0) {
a = l.shift().split('#');
o.details = new PlanetDetails(a.shift(), a.shift(), a.shift(), a.shift(), a.shift(), a.shift(),
a.join('#'));
if (o.details.owner != '') {
pl.push(o.details.owner);
a = allies.get(o.details.owner);
a.planets.push(o);
}
}
locations.put(o.id, o);
}
}
function parsePlayers(l, pl)
{
var a,o,i,str,np;
str = ""; np = 0;
for (i=0;i<pl.length;i++)
{
if (str.indexOf('#'+pl[i]+'#') != -1)
continue;
np++;
str += '#' + pl[i] + '#';
}
players = new Hashtable();
for (i=0;i<np;i++)
{
a = l.shift().split('#');
players.put(a[0], a[1]);
}
}
function linkMainData()
{
var i, f, a, p, fl;
fl = fleets.keys();
for (i=0;i<fl.length;i++)
{
f = fleets.get(fl[i]);
a = allies.get(f.owner);
if (a)
a.fleets.push(f);
if (f.orders.oType == 1)
{
f.orders.to = locations.get(f.orders.toId);
f.orders.from = locations.get(f.orders.fromId);
f.orders.cur = locations.get(f.orders.curId);
if (f.orders.wait)
{
f.orders.wait.from = f.orders.from;
f.orders.wait.loc = f.orders.to;
}
}
else if (f.orders.oType == 2)
{
f.orders.loc = locations.get(f.orders.locId);
f.orders.from = locations.get(f.orders.fromId);
}
else
{
p = locations.get(f.orders.locId);
f.orders.loc = p;
p.fleets.push(f);
if (a && p.details && p.details.owner != a.id)
{
var g;
if (a.gasAt.containsKey(p.id))
g = a.gasAt.get(p.id);
else
g = 0;
g += parseInt(f.ships[0], 10);
a.gasAt.put(p.id, g);
}
}
}
}
function prepareUpdate()
{
var i,k;
fSel = new Array();
k = fleets.keys();
for (i=0;i<k.length;i++)
{
var f = fleets.get(k[i]);
if (f.selected)
fSel.push(f.id);
}
}
function mainDataUpdate()
{
if (autoLock)
{
setTimeout('mainDataUpdate()', 500);
return;
}
autoLock = true;
prepareUpdate();
x_getFleetsList(parseMainData);
}
// The infamous filtering function
function applyFilters()
{
var i, keys, pln, flt;
ppList = new Hashtable(); apList = new Hashtable(); opList = new Hashtable();
mfList = new Array(); wfList = new Array();
keys = locations.keys(); pln = new Array();
for (i=0;i<keys.length;i++)
{
var p = locations.get(keys[i]);
if ( ( listLocations == 0
|| listLocations == 1 && p.details && p.details.owner == myself.id
|| listLocations == 2 && p.details && p.details.owner != myself.id && p.details.owner != ''
|| listLocations == 3 && (!p.details || p.details.owner == '')
) && ( sType != 1
|| sType == 1 && (sText == '' || p.name.toLowerCase().indexOf(sText.toLowerCase()) != -1)
)
)
pln.push(keys[i]);
}
keys = fleets.keys(); flt = new Array();
for (i=0;i<keys.length;i++)
{
var f = fleets.get(keys[i]);
if ( (listMode == 0 || listMode - 1 == f.mode)
&& ( fDispMode == 0
|| fDispMode == 1 && f.orders.oType == 0 && f.orders.canMove == 'Y'
|| fDispMode == 2 && f.orders.oType == 0 && f.orders.canMove != 'Y'
|| fDispMode > 2 && fDispMode - 2 == f.orders.oType
) && ( alliesMode == 0
|| alliesMode == 1 && f.owner == myself.id
|| alliesMode == 2 && f.owner != myself.id && allies.get(f.owner)
|| alliesMode == 3 && !allies.get(f.owner)
) && ( sType == 1
|| sType == 0 && (sText == '' || f.name.toLowerCase().indexOf(sText.toLowerCase()) != -1)
|| sType == 2 && (sText == '' || players.get(f.owner).toLowerCase().indexOf(sText.toLowerCase()) != -1)
)
)
flt.push(keys[i]);
}
if (fDispMode < 3)
{
if (listLocations < 2)
for (i=0;i<myself.planets.length;i++)
ppList.put(myself.planets[i].id, new FilteredLocation(myself.planets[i].id));
if (listLocations == 0 || listLocations == 2)
{
keys = allies.keys();
for (i=0;i<keys.length;i++)
{
var j, p=allies.get(keys[i]);
if (p.isMe)
continue;
for (j=0;j<p.planets.length;j++)
apList.put(p.planets[j].id, new FilteredLocation(p.planets[j].id));
}
}
}
var pStr = '#'+pln.join('#')+'#';
for (i=0;i<flt.length;i++)
{
var p, l, f = fleets.get(flt[i]);
switch (f.orders.oType)
{
case 0:
case 3:
case 4:
p = f.orders.loc;
if (pStr.indexOf('#' + p.id + '#') == -1)
continue;
if (!p.details || p.details.owner == "")
l = opList;
else if (p.details && p.details.owner != myself.id)
l = apList;
else
l = ppList;
p = l.get(f.orders.locId);
if (!p)
{
p = new FilteredLocation(f.orders.locId);
l.put(p.id, p);
}
p.fleets.push(f.id);
break;
case 1:
if ( pStr.indexOf('#' + f.orders.toId + '#') == -1
&& pStr.indexOf('#' + f.orders.fromId + '#') == -1
&& pStr.indexOf('#' + f.orders.curId + '#') == -1
)
continue;
mfList.push(f);
break;
case 2:
if ( pStr.indexOf('#' + f.orders.locId + '#') == -1
&& pStr.indexOf('#' + f.orders.fromId + '#') == -1
)
continue;
wfList.push(f);
break;
}
}
}
function changeFilters(fVar, fVal)
{
var r;
eval("r = ("+fVar+"==fVal);");
if (r)
return;
if (autoLock)
{
setTimeout('changeFilters(fVar, fVal)', 500);
return;
}
lockUpdate();
x_setFilter(fVar, fVal, function(){ });
eval(fVar + '=fVal;');
applyFilters();
drawMainContents();
unlockUpdate();
}
function selectFleet(id) {
if (autoLock) {
setTimeout('selectFleet('+id+')', 500);
return;
}
autoLock = true;
var f = fleets.get(id);
f.selected = !f.selected;
if (f.orders.oType == 1) {
mFleetSelected += (f.selected ? 1 : -1);
updateMovingSelection();
} else if (f.orders.oType == 2) {
wFleetSelected += (f.selected ? 1 : -1);
updateWaitingSelection();
} else {
var loc = f.orders.loc;
loc.selectedFleets += (f.selected ? 1 : -1);
loc.updateSelection();
}
updateActions();
autoLock = false;
}
function updateWaitingSelection () {
var e = document.getElementById('f-hssb-sel');
if (!e) {
return;
}
if (wFleetSelectable == 0) {
e.innerHTML = '&nbsp;';
return;
}
e.innerHTML = '<input type="checkbox" name="wsel-all" id="wsel-all" onclick="selectAllWaitingFleets()"'
+ (wFleetSelectable == wFleetSelected ? ' checked="checked"' : '') + ' />';
}
function selectAllWaitingFleets () {
if (autoLock) {
setTimeout('selectAllWaitingFleets()', 500);
return;
}
autoLock = true;
if (wFleetSelectable == 0) {
autoLock = false;
return;
}
for (var i in wfList) {
var e = document.getElementById('fsel' + wfList[i].id);
if (!e) {
continue;
}
e.checked = wfList[i].selected = !(wFleetSelectable == wFleetSelected);
}
if (wFleetSelectable == wFleetSelected) {
wFleetSelected = 0;
} else {
wFleetSelected = wFleetSelectable;
}
updateActions();
autoLock = false;
}
function updateMovingSelection () {
var e = document.getElementById('f-move-sel');
if (!e) {
return;
}
if (mFleetSelectable == 0) {
e.innerHTML = '&nbsp;';
return;
}
e.innerHTML = '<input type="checkbox" name="msel-all" id="msel-all" onclick="selectAllMovingFleets()"'
+ (mFleetSelectable == mFleetSelected ? ' checked="checked"' : '') + ' />';
}
function selectAllMovingFleets () {
if (autoLock) {
setTimeout('selectAllMovingFleets()', 500);
return;
}
autoLock = true;
if (mFleetSelectable == 0) {
autoLock = false;
return;
}
for (var i in mfList) {
var e = document.getElementById('fsel' + mfList[i].id);
if (!e) {
continue;
}
e.checked = mfList[i].selected = !(mFleetSelectable == mFleetSelected);
}
if (mFleetSelectable == mFleetSelected) {
mFleetSelected = 0;
} else {
mFleetSelected = mFleetSelectable;
}
updateActions();
autoLock = false;
}
function updateActions()
{
var cRen = false, cTraj = true, cMove = true, cSwitch = true,
cMerge = true, cDisband = true, cSell = myself.canSell, cCancelSale = myself.canSell;
var i, n, ns;
for (i=n=ns=0;i<fDisp.length;i++)
{
var f = fDisp[i];
if (!f.selected)
continue;
ns += parseInt(f.ships[0], 10) + parseInt(f.ships[1], 10) + parseInt(f.ships[2], 10) + parseInt(f.ships[3], 10);
cRen = true;
cTraj = cTraj && f.orders.oType == 1;
cMove = cMove && (f.orders.oType < 3 && f.orders.oType != 0 || f.orders.canMove == 'Y');
cMerge = cMerge && !(f.orders.oType == 3 || f.orders.oType == 4) && (f.orders.oType != 0 || f.orders.canMove == 'Y');
cSwitch = cSwitch && !(f.orders.oType == 3 || f.orders.oType == 4) && (f.orders.oType != 1 && (
!f.orders.loc.details || f.orders.loc.details && f.orders.loc.details.owner != f.owner
) || f.orders.oType == 1 && (
!f.orders.to.details || f.orders.to.details && f.orders.to.details.owner != f.owner
));
cDisband = cDisband && (f.owner == myself.id) && !(f.orders.oType == 3 || f.orders.oType == 4);
cSell = cSell && (f.owner == myself.id) && (f.orders.oType == 0) && (f.mode == 0) && (f.orders.canMove == 'Y');
cCancelSale = cCancelSale && (f.orders.oType == 3 || f.orders.oType == 4) && !f.orders.inBundle && (f.owner == myself.id);
n++;
}
if (!cRen)
{
document.getElementById('factions').innerHTML = actionText[0];
return;
}
i = '<a href="#" onClick="clearSelection();return false">' + actionText[9] + '</a>'
+ ' - <a href="#" onClick="renameSelected();return false">' + actionText[1] + '</a>';
if (cTraj && n == 1)
i += ' - <a href="#" onClick="viewTrajectory();return false">' + actionText[8] + '</a>';
if (cMove)
i += ' - <a href="#" onClick="moveSelected();return false">' + actionText[2] + '</a>';
if (cSwitch)
i += ' - <a href="#" onClick="switchSelected();return false">' + actionText[3] + '</a>';
if (cMerge && n > 1)
i += ' - <a href="#" onClick="mergeSelected();return false">' + actionText[5] + '</a>';
if (cMerge && n == 1 && ns > 1)
i += ' - <a href="#" onClick="splitSelected();return false">' + actionText[4] + '</a>';
if (cSell)
i += ' - <a href="#" onClick="sellSelected();return false">' + actionText[6] + '</a>';
if (cCancelSale)
{
if (n == 1)
i += ' - <a href="#" onClick="viewSaleSelected();return false">' + actionText[11] + '</a>';
i += ' - <a href="#" onClick="cancelSaleSelected();return false">' + actionText[10] + '</a>';
}
if (cDisband)
i += ' - <a href="#" onClick="disbandSelected();return false">' + actionText[7] + '</a>';
document.getElementById('factions').innerHTML = i;
}
function drawFleetLine(fleet,type,hasSel) {
var o = allies.get(fleet.owner);
var i, str = '<tr class="fl'+type+'">';
var sc = '';
if (hasSel)
{
str += '<td class="fsel">';
if (o && (fleet.orders.oType != 3 && fleet.orders.oType != 4 || !fleet.orders.inBundle))
{
str += '<input type="checkbox" id="fsel'+fleet.id+'" name="fsel'+fleet.id+'" value="1" '
+ (fleet.selected ? 'checked="checked" ' : '')
+ ' onClick="selectFleet('+fleet.id+');return true" />';
fDisp.push(fleet);
sc = ' onclick="with (document.getElementById(\'fsel'+fleet.id+'\')) { checked = !checked; };'
+ 'selectFleet('+fleet.id+');return true" ';
var loc = fleet.orders.loc;
loc.selectableFleets ++;
loc.selectedFleets += (fleet.selected ? 1 : 0);
} else {
str += '&nbsp;';
}
str += '</td>';
}
str += '<td';
if (myself.id != fleet.owner) {
str += '><a href="message?a=c&ct=0&id=' + fleet.owner + '">';
} else {
str += sc + '>';
}
str += players.get(fleet.owner);
str += '</td><td';
if (o)
str += ' onClick="renameFleet(' + fleet.id + ');return false"';
str += '>' + fleet.name + '</td><td class="fhs"' + sc + '>';
if (o)
{
var used = fleet.ships[0] * o.gSpace + fleet.ships[1] * o.fSpace;
var haul = fleet.ships[2] * o.cHaul + fleet.ships[3] * o.bHaul;
if (haul == 0)
str += 'N/A';
else
{
var hp = Math.round(used * 100 / haul);
str += (hp > 200) ? '&gt;200%' : (hp + '%');
}
}
else
str += '&nbsp;';
str += '</td>';
for (i=0;i<4;i++)
str += '<td class="fshp"' + sc + '>'+formatNumber(fleet.ships[i])+'</td>';
str += '<td class="fpwr"' + sc + '>'+formatNumber(fleet.power)+'</td><td class="fstat"' + sc + '>';
if (fleet.orders.oType == 0)
str += (fleet.mode == 1 ? statusText[0] : statusText[1]) + ', ' + (fleet.orders.canMove == 'Y' ? statusText[2] : statusText[3]);
else if (fleet.orders.oType == 3)
str += statusText[4] + (fleet.orders.inBundle ? statusText[6] : '');
else if (fleet.orders.oType == 4)
str += statusText[5];
str += '</td></tr>';
return str;
}
function drawMovingFleetLine(fleet, hasSel)
{
var o = allies.get(fleet.owner);
var i, str = '<tr><td class="flt"><table class="mfltl">';
var sc = '';
str += '<tr class="fl'+(fleet.owner==myself.id?'own':'ally')+'">';
if (hasSel) {
str += '<td class="fsel" rowspan="2"><input type="checkbox" id="fsel' + fleet.id + '" name="fsel'
+ fleet.id + '" value="1" ' + (fleet.selected ? 'checked="checked" ' : '')
+ ' onClick="selectFleet(' + fleet.id + ');return true" /></td>';
mFleetSelectable ++;
mFleetSelected += (fleet.selected ? 1 : 0);
fDisp.push(fleet);
sc = ' onclick="with (document.getElementById(\'fsel'+fleet.id+'\')) { checked = !checked; };'
+ 'selectFleet('+fleet.id+');return true" ';
}
str += '<td class="fown" rowspan="2"';
if (myself.id != fleet.owner) {
str += '><a href="message?a=c&ct=0&id=' + fleet.owner + '">';
} else {
str += sc + '>';
}
str += players.get(fleet.owner);
if (myself.id != fleet.owner)
str += '</a>';
str += '</td><td onClick="renameFleet(' + fleet.id + ');return false"';
str += ' class="fname" rowspan="2">' + fleet.name + '</td><td class="fhs"' + sc + '>';
var used = fleet.ships[0] * o.gSpace + fleet.ships[1] * o.fSpace;
var haul = fleet.ships[2] * o.cHaul + fleet.ships[3] * o.bHaul;
if (haul == 0)
str += 'N/A';
else
{
var hp = Math.round(used * 100 / haul);
str += (hp > 200) ? '&gt;200%' : (hp + '%');
}
str += '</td>';
for (i=0;i<4;i++)
str += '<td class="fshp"' + sc + '>'+formatNumber(fleet.ships[i])+'</td>';
str += '<td class="fpwr"' + sc + '>'+formatNumber(fleet.power)+'</td>';
str += '<td class="fstat"' + sc + '>' + (fleet.mode == 1 ? statusText[0] : statusText[1]) + '</td></tr>';
str += '<tr class="fl'+(fleet.owner==myself.id?'own':'ally')+'">';
str += '<td class="fdest" colspan="2"><a href="planet?id=' + fleet.orders.curId + '">' + fleet.orders.cur.name + '</a>';
if (fleet.orders.cur.details && fleet.orders.cur.details.tag != '') {
str += ' [' + fleet.orders.cur.details.tag + ']';
}
str += '</td><td class="floc" colspan="2"><a href="planet?id=' + fleet.orders.toId + '">' + fleet.orders.to.name + '</a>';
if (fleet.orders.to.details && fleet.orders.to.details.tag != '') {
str += ' [' + fleet.orders.to.details.tag + ']';
}
str += '</td><td class="feta"' + sc + '>' + fleet.orders.eta + ' min</td><td class="fstd" colspan="2"' + sc + '>';
if (fleet.orders.wait)
{
str += fleet.orders.wait.left + 'h (';
if (fleet.orders.wait.maxLoss == 0)
str += '0%';
else
str += fleet.orders.wait.minLoss + '% - ' + fleet.orders.wait.maxLoss + '%';
str += ')';
}
else
str += 'N/A';
str += '</td></tr></table></td></tr>';
return str;
}
function drawWaitingFleetLine(fleet,hasSel)
{
var o = allies.get(fleet.owner);
var i, str = '<tr><td class="flt"><table class="wfltl">';
var sc = '';
str += '<tr class="fl'+(fleet.owner==myself.id?'own':'ally')+'">';
if (hasSel) {
str += '<td class="fsel" rowspan="2"><input type="checkbox" name="fsel' + fleet.id
+ '" id="fsel'+fleet.id+'" value="1" ' + (fleet.selected ? 'checked="checked" ' : '')
+ ' onClick="selectFleet(' + fleet.id + ');return true" /></td>';
wFleetSelectable ++;
wFleetSelected += (fleet.selected ? 1 : 0);
fDisp.push(fleet);
sc = ' onclick="with (document.getElementById(\'fsel'+fleet.id+'\')) { checked = !checked; };'
+ 'selectFleet('+fleet.id+');return true" ';
}
str += '<td class="fown" rowspan="2"';
if (myself.id != fleet.owner) {
str += '><a href="message?a=c&ct=0&id=' + fleet.owner + '">';
} else {
str += sc + '>';
}
str += players.get(fleet.owner);
if (myself.id != fleet.owner)
str += '</a>';
str += '</td><td onClick="renameFleet(' + fleet.id + ');return false"';
str += ' class="fname" rowspan="2">' + fleet.name + '</td><td ' + sc + 'class="fhs">';
var used = fleet.ships[0] * o.gSpace + fleet.ships[1] * o.fSpace;
var haul = fleet.ships[2] * o.cHaul + fleet.ships[3] * o.bHaul;
if (haul == 0)
str += 'N/A';
else
{
var hp = Math.round(used * 100 / haul);
str += (hp > 200) ? '&gt;200%' : (hp + '%');
}
str += '</td>';
for (i=0;i<4;i++)
str += '<td' + sc + ' class="fshp">'+formatNumber(fleet.ships[i])+'</td>';
str += '<td' + sc + ' class="fpwr">'+formatNumber(fleet.power)+'</td>';
str += '<td' + sc + ' class="fstat">' + (fleet.mode == 1 ? statusText[0] : statusText[1]) + '</td></tr>';
str += '<tr class="fl'+(fleet.owner==myself.id?'own':'ally')+'">'
+ '<td class="floc" colspan="2"><a href="planet?id=' + fleet.orders.locId + '">' + fleet.orders.loc.name + '</a>';
if (fleet.orders.loc.details && fleet.orders.loc.details.tag != '') {
str += ' [' + fleet.orders.loc.details.tag + ']';
}
str += '</td><td' + sc + ' class="ftime" colspan="2">' + fleet.orders.spent + 'h</td><td' + sc + ' class="ftime" colspan="2">'
+ fleet.orders.left + 'h</td><td' + sc + ' class="floss">';
if (fleet.orders.maxLoss == 0)
str += '0%';
else
str += fleet.orders.minLoss + '% - ' + fleet.orders.maxLoss + '%';
str += '</td></tr></table></td></tr>';
return str;
}
function drawMainContents()
{
fDisp = new Array();
if (ppList.size() == 0 && apList.size() == 0 && opList.size() == 0 && mfList.length == 0 && wfList.length == 0)
{
document.getElementById('fmain').innerHTML = '<center>'+noFleetsFound+'</center>';
return;
}
var i,sz,keys,j,p,f,str = '';
if ((sz = ppList.size()) != 0)
{
str += '<h1>'+sectionTitles[0]+'</h1>';
keys = ppList.keys();
keys.sort(sortPPList);
for (i=0;i<sz;i++)
str += drawPlanetBox(ppList.get(keys[i]));
}
if ((sz = apList.size()) != 0)
{
str += '<h1>'+sectionTitles[1]+'</h1>';
keys = apList.keys();
keys.sort(sortAPList);
for (i=0;i<sz;i++)
str += drawPlanetBox(apList.get(keys[i]));
}
if ((sz = opList.size()) != 0)
{
str += '<h1>'+sectionTitles[2]+'</h1>';
keys = opList.keys();
keys.sort(sortOPList);
for (i=0;i<sz;i++)
str += drawPlanetBox(opList.get(keys[i]));
}
if (mfList.length != 0) {
mFleetSelectable = mFleetSelected = 0;
str += '<h1>'+sectionTitles[3]+'</h1>';
str += '<table class="planet"><tr><td class="flt">' + drawMovingHeader(true) + '</td></tr>';
mfList.sort(sortMovingFleets);
for (j=0;j<mfList.length;j++) {
str += drawMovingFleetLine(mfList[j], true);
}
str += '</table>';
}
if (wfList.length != 0) {
wFleetSelectable = wFleetSelected = 0;
str += '<h1>'+sectionTitles[4]+'</h1>';
str += '<table class="planet"><tr><td class="flt">' + drawWaitingHeader(true) + '</td></tr>';
wfList.sort(sortWaitingFleets);
for (j=0;j<wfList.length;j++) {
str += drawWaitingFleetLine(wfList[j], true);
}
str += '</table>';
}
document.getElementById('fmain').innerHTML = str;
keys = locations.keys();
for (i=0;i<keys.length;i++) {
locations.get(keys[i]).updateSelection();
}
updateMovingSelection();
updateWaitingSelection();
updateActions();
}
function renameFleet(id)
{
if (autoLock)
{
setTimeout('renameFleet(id)', 500);
return;
}
lockUpdate();
var str = "";
while (str == "")
{
str = getNewFleetName(false);
if (typeof str == 'object' && !str)
{
unlockUpdate();
return;
}
if (str == "")
alertFleetName(0);
else if (str.length > 64)
{
alertFleetName(1);
str = "";
}
else if (str.length < 3)
{
alertFleetName(2);
str = "";
}
}
x_renameFleets(id, str, renameCallback);
}
function renameSelected()
{
if (autoLock)
{
setTimeout('renameSelected()', 500);
return;
}
lockUpdate();
var str = "";
while (str == "")
{
str = getNewFleetName(false);
if (typeof str == 'object' && !str)
{
unlockUpdate();
return;
}
if (str == "")
alertFleetName(0);
else if (str.length > 64)
{
alertFleetName(1);
str = "";
}
else if (str.length < 3)
{
alertFleetName(2);
str = "";
}
}
var s = new Array();
for (i=0;i<fDisp.length;i++)
{
if (fDisp[i].selected)
s.push(fDisp[i].id);
}
x_renameFleets(s.join('#'), str, renameCallback);
}
function renameCallback(str)
{
if (str.indexOf('ERR#') == 0)
{
var l = str.split('#');
alertFleetName(parseInt(l[1], 10));
unlockUpdate();
}
else
{
prepareUpdate();
parseMainData(str);
}
}
function mergeSelected()
{
if (autoLock)
{
setTimeout('mergeSelected()', 500);
return;
}
lockUpdate();
var str = " ";
while (str == " ")
{
str = getMergedFleetName();
if (typeof str == 'object' && !str)
{
unlockUpdate();
return;
}
if (str.length > 64)
{
alertFleetMerge(0);
str = " ";
}
else if (str.length < 3 && str != '')
{
alertFleetMerge(1);
str = " ";
}
}
var i, s = new Array();
for (i=0;i<fDisp.length;i++)
{
if (fDisp[i].selected)
s.push(fDisp[i].id);
}
x_mergeFleets(s.join('#'), str, mergeCallback);
}
function mergeCallback(str)
{
if (str.indexOf('ERR#') == 0)
{
var l = str.split('#');
alertFleetMerge(parseInt(l[1], 10));
unlockUpdate();
}
else
{
clearSelection();
prepareUpdate();
parseMainData(str);
}
}
function switchSelected()
{
if (autoLock)
{
setTimeout('switchSelected()', 500);
return;
}
lockUpdate();
var s = new Array();
for (i=0;i<fDisp.length;i++)
{
if (fDisp[i].selected)
s.push(fDisp[i].id);
}
x_switchStatus(s.join('#'), switchCallback);
}
function switchCallback(str)
{
if (str.indexOf('ERR#') == 0)
{
var l = str.split('#');
alertFleetSwitch(parseInt(l[1], 10));
unlockUpdate();
}
else
{
clearSelection();
prepareUpdate();
parseMainData(str);
}
}
function disbandSelected()
{
if (autoLock)
{
setTimeout('disbandSelected()', 500);
return;
}
lockUpdate();
var s = new Array();
for (i=0;i<fDisp.length;i++)
{
if (fDisp[i].selected)
s.push(fDisp[i].id);
}
if (confirmDisband(s.length >1))
x_disbandFleets(s.join('#'), disbandCallback);
else
unlockUpdate();
}
function disbandCallback(str)
{
if (str.indexOf('ERR#') == 0)
{
var l = str.split('#');
alertFleetDisband(parseInt(l[1], 10));
unlockUpdate();
}
else
{
prepareUpdate();
parseMainData(str);
}
}
function splitSelected()
{
if (autoLock)
{
setTimeout('splitSelected()', 500);
return;
}
lockUpdate();
splitParam = new Array();
for (var i=0;i<fDisp.length;i++)
if (fDisp[i].selected)
{
splitParam[0] = fDisp[i];
break;
}
splitParam[1] = splitParam[3] = splitParam[4] = splitParam[5] = splitParam[6] = 0;
splitParam[2] = 1; splitParam[9] = '';
onMainPage = false;
drawSplitPage();
}
function setSplitType(type)
{
if (type == splitParam[1])
return;
splitParam[1] = type;
var i, flds = ['sgas','sfgt','scru','sbcr'];
for (i=0;i<4;i++)
{
var e = document.getElementById(flds[i]);
if (e)
e.disabled = (type == 1);
}
if (type == 1)
updateAutoSplit();
else
{
for (i=0;i<4;i++)
{
var e = document.getElementById(flds[i]);
if (e)
e.value = splitParam[i+3];
}
updateSplitHaul();
updateSplitOk();
}
}
function updateAutoSplit()
{
var ships = [0,0,0,0];
var o = allies.get(splitParam[0].owner);
var flds = ['sgas','sfgt','scru','sbcr'];
var i;
for (i=0;i<4;i++)
{
var e;
ships[i] = Math.floor(splitParam[0].ships[i] / (splitParam[2] + 1));
e = document.getElementById(flds[i]);
if (e)
{
e.disabled = true;
e.value = ships[i];
}
}
if (splitParam[0].ships[2] > 0 || splitParam[0].ships[3] > 0)
{
splitParam[7] = ships[0] * o.gSpace + ships[1] * o.fSpace;
splitParam[8] = ships[2] * o.cHaul + ships[3] * o.bHaul;
document.getElementById('hused').innerHTML = splitParam[7];
document.getElementById('havail').innerHTML = splitParam[8];
}
var s=0;
for (i=0;i<4;i++)
s += ships[i];
var canSplit = (s > 0);
if (splitParam[0].orders.oType == 2 || splitParam[0].orders.oType == 1 && splitParam[0].orders.hyperspace)
canSplit = canSplit && (splitParam[7] <= splitParam[8]);
document.getElementById('bsplit').disabled = !canSplit;
}
function setSplitCount(amount)
{
splitParam[2] = amount;
if (splitParam[1] == 0)
{
updateSplitHaul();
updateSplitOk();
}
else
updateAutoSplit();
}
function setSplitShips(type,amount)
{
var flds = ['sgas','sfgt','scru','sbcr'];
if (amount < 0 || isNaN(amount))
return;
splitParam[type+3] = amount;
updateSplitHaul();
updateSplitOk();
}
function updateSplitHaul()
{
if (splitParam[0].ships[2] == 0 && splitParam[0].ships[3] == 0)
{
splitParam[7] = splitParam[8] = 0;
return;
}
var o = allies.get(splitParam[0].owner);
splitParam[7] = splitParam[3] * o.gSpace + splitParam[4] * o.fSpace;
splitParam[8] = splitParam[5] * o.cHaul + splitParam[6] * o.bHaul;
document.getElementById('hused').innerHTML = splitParam[7];
document.getElementById('havail').innerHTML = splitParam[8];
}
function updateSplitOk()
{
var ships = [0,0,0,0];
var diffs = [0,0,0,0];
var i,s1=0,s2=0,neg=false;
for (i=0;i<4;i++)
{
ships[i] = splitParam[i+3] * splitParam[2];
s1 += ships[i];
diffs[i] = splitParam[0].ships[i] - ships[i];
neg = neg || (diffs[i] < 0);
s2 += diffs[i];
}
var canSplit = (s1 > 0 && !neg && s2 > 0);
if (splitParam[0].orders.oType == 2 || splitParam[0].orders.oType == 1 && splitParam[0].orders.hyperspace)
{
var ou, os, o = allies.get(splitParam[0].owner);
ou = diffs[0] * o.gSpace + diffs[1] * o.fSpace;
os = diffs[2] * o.cHaul + diffs[3] * o.bHaul;
canSplit = canSplit && (splitParam[7] <= splitParam[8]) && (ou <= os);
}
document.getElementById('bsplit').disabled = !canSplit;
}
function cancelSplit()
{
prepareUpdate();
x_getFleetsList(parseMainData);
}
function doFleetSplit()
{
document.getElementById('bsplit').disabled = true;
if (splitParam[1] == 0)
x_manualSplit(splitParam[0].id, splitParam[9], splitParam[2], splitParam[3], splitParam[4], splitParam[5], splitParam[6], splitCallback);
else
x_autoSplit(splitParam[0].id, splitParam[9], splitParam[2], splitCallback);
}
function splitCallback(str)
{
if (str.indexOf('ERR#') == 0) {
var l = str.split('#');
alertFleetSplit(parseInt(l[1], 10));
document.getElementById('bsplit').disabled = false;
} else {
clearSelection();
prepareUpdate();
parseMainData(str);
}
}
function moveSelected()
{
if (autoLock)
{
setTimeout('moveSelected()', 500);
return;
}
lockUpdate();
orderFleets = new Array();
for (var i=0;i<fDisp.length;i++)
if (fDisp[i].selected)
orderFleets.push(fDisp[i].id);
moveTo = waitTime = -1;
moveToLoc = null;
onMainPage = false;
guessOrders = true;
drawOrdersPage();
updateOrdersPage();
}
function cancelOrders()
{
prepareUpdate();
x_getFleetsList(parseMainData);
}
function setNewOrders()
{
var mode, e;
if ((e = document.getElementById('flmode')))
mode = e.options[e.selectedIndex].value;
else
mode = 0;
x_setOrders(orderFleets.join('#'), moveTo, waitTime, mode, ordersCallback);
}
function ordersCallback(str)
{
if (str.indexOf('ERR#') == 0)
{
var l = str.split('#');
alertFleetOrders(parseInt(l[1], 10));
}
else
{
clearSelection();
prepareUpdate();
parseMainData(str);
}
}
function updateOrdersPage()
{
if (!moveToLoc)
{
if (!readingMoveLocation)
{
readingMoveLocation = true;
x_getLocation(moveTo, gotLocation);
}
return;
}
document.getElementById('oself').innerHTML = getOSelFleets();
document.getElementById('oavaf').innerHTML = getOAvailFleets();
document.getElementById('moveto').innerHTML = getMoveToLine();
document.getElementById('standby').innerHTML = getStandByLine();
document.getElementById('odmode').innerHTML = getModeLine();
document.getElementById('chordc').innerHTML = getOrderLinks();
updateTrajectories();
}
function updateTrajectories()
{
if (readingMoveLocation || trajLock)
return;
var i, f;
for (i=0;i<orderFleets.length;i++)
{
var f = fleets.get(orderFleets[i]);
var e = document.getElementById('ft' + f.id);
if (!e)
continue;
if (moveTo == -1)
{
e.innerHTML = getTrajectoryText(f.id, []);
continue;
}
var t = getTrajectory(f, moveToLoc);
e.innerHTML = getTrajectoryText(f.id, t);
}
}
function getOSelFleets()
{
if (!orderFleets.length)
{
selCanHS = true;
return '<p>' + actionText[0] + '</p>';
}
var i,str = '<table class="oself"><tr>' + foSelHeader + '</tr>';
selCanHS = true; gWait = gDest = -2;
var n = new Array();
sMovex = null; sMovey = null;
orderFleets.sort(sortOrderFleets);
for (i=0;i<orderFleets.length;i++)
{
var f = fleets.get(orderFleets[i]), o = allies.get(f.owner);
var used = f.ships[0] * o.gSpace + f.ships[1] * o.fSpace;
var haul = f.ships[2] * o.cHaul + f.ships[3] * o.bHaul;
var canHS = (used <= haul);
selCanHS = selCanHS && canHS;
if (!canHS)
{
var fLoc = (f.orders.oType != 1 ? f.orders.loc : f.orders.cur);
if (typeof sMovex == 'object')
{
sMovex = fLoc.x; sMovey = fLoc.y;
}
else if (fLoc.x != sMovex || fLoc.y != sMovey)
continue;
}
n.push(f.id);
if (guessOrders)
{
if (f.orders.oType == 1)
{
if (gDest == -2 && gWait == -2)
{
gDest = (f.orders.toId == f.orders.curId ? -1 : f.orders.toId);
if (f.orders.wait)
gWait = f.orders.wait.left;
else
gWait = -1;
}
else if (gDest != f.orders.toId || gWait > 0 && !f.orders.wait || f.orders.wait && gWait != f.orders.wait.left)
gWait = gDest = -1;
}
else if (f.orders.oType == 2)
{
if (gWait == -2 && gDest == -2)
{
gDest = -1;
gWait = f.orders.left;
}
else if (gDest > 0 || f.orders.left != gWait)
gWait = gDest = -1;
}
else
gWait = gDest = -1;
orderMode = parseInt(f.mode, 10);
}
var oc = ' onClick="removeOrdersSelection('+f.id+')"';
str += '<tr class="' + (f.owner == myself.id ? 'flown' : 'flally') + '"><td class="fown"'+oc+'>'
+ players.get(f.owner) + '</td><td'+oc+' class="fname">' + f.name + '</td><td'+oc+' class="fhs">';
if (haul == 0)
str += 'N/A';
else
{
var hp = Math.round(used * 100 / haul);
str += (hp > 200) ? '&gt;200%' : (hp + '%');
}
str += '</td><td'+oc+' class="fshp">' + formatNumber(f.ships[0]) + ' / ' + formatNumber(f.ships[1]) + ' / ';
str += formatNumber(f.ships[2]) + ' / ' + formatNumber(f.ships[3]) + '</td><td'+oc+' class="fpwr">';
str += formatNumber(f.power) + '</td><td class="ftraj" id="ft' + f.id + '">&nbsp;</td></tr>';
}
orderFleets = n;
str += '</table>';
guessOrders = false;
if (gWait > 0)
waitTime = gWait;
if (gDest > 0)
{
moveTo = gDest;
moveToLoc = locations.get(moveTo);
}
return str;
}
function getOAvailFleets()
{
// Fleets are available if:
// they are not selected
// AND ( they are idling AND can move
// OR they are moving
// OR they are waiting in HS )
// AND ( there is a destination
// AND ( the fleet is HS capable
// OR the fleet is not HS capable AND the target is in the same system )
// OR there is no destination )
// AND ( there are HS stand-by orders AND the fleet is HS capable
// OR there are no HS stand-by orders )
var i, sst = '#' + orderFleets.join('#') + '#';
var afl = new Array(), fk = fleets.keys();
for (i=0;i<fk.length;i++)
{
if (sst.indexOf('#'+fk[i]+'#') != -1)
continue;
var f = fleets.get(fk[i]);
var o = allies.get(f.owner);
if (!o)
continue;
var hs = ((f.ships[0] * o.gSpace + f.ships[1] * o.fSpace) <= (f.ships[2] * o.cHaul + f.ships[3] * o.bHaul));
var fLoc = (f.orders.oType != 1 ? f.orders.loc : f.orders.cur);
if ( f.orders.oType == 0 && f.orders.canMove != 'Y'
|| moveTo != -1 && !hs && (fLoc.x != moveToLoc.x || fLoc.y != moveToLoc.y)
|| waitTime != -1 && !hs
|| !selCanHS && !hs && (fLoc.x != sMovex || fLoc.y != sMovey)
|| f.orders.oType >= 3
)
continue;
afl.push(f);
}
if (!afl.length)
return '<p>' + noFleetsFound + '</p>';
var i,str = '<table class="oavaf"><tr>' + foAvaHeader + '</tr>';
afl.sort(sortAvailFleets);
for (i=0;i<afl.length;i++)
{
var f = afl[i], o = allies.get(f.owner);
var used = f.ships[0] * o.gSpace + f.ships[1] * o.fSpace;
var haul = f.ships[2] * o.cHaul + f.ships[3] * o.bHaul;
str += '<tr onClick="addOrdersSelection('+f.id+')" class="' + (f.owner == myself.id ? 'flown' : 'flally') + '"><td class="fown">';
str += players.get(f.owner) + '</td><td class="fname">' + f.name + '</td><td class="fhs">';
if (haul == 0)
str += 'N/A';
else
{
var hp = Math.round(used * 100 / haul);
str += (hp > 200) ? '&gt;200%' : (hp + '%');
}
str += '</td><td class="fshp">' + formatNumber(f.ships[0]) + ' / ' + formatNumber(f.ships[1]) + ' / ';
str += formatNumber(f.ships[2]) + ' / ' + formatNumber(f.ships[3]) + '</td><td class="fpwr">';
str += formatNumber(f.power) + '</td><td class="fco">';
var m = parseInt(f.mode, 10);
if (f.orders.oType == 0)
str += curOrdersTxt[m] + f.orders.loc.name + curOrdersTxt[2 + m];
else if (f.orders.oType == 1)
str += curOrdersTxt[m+4] + f.orders.to.name + curOrdersTxt[m+6];
else
str += curOrdersTxt[m+8] + f.orders.loc.name + curOrdersTxt[m+10];
str += '</td></tr>';
}
str += '</table>';
return str;
}
function removeOrdersSelection(id)
{
var n = new Array(), i;
for (i=0;i<orderFleets.length;i++)
if (orderFleets[i] != id)
n.push(orderFleets[i]);
orderFleets = n;
updateOrdersPage();
}
function addOrdersSelection(id)
{
orderFleets.push(id);
updateOrdersPage();
}
function setOrdersTime()
{
var str = "", nt=waitTime;
while (str == "")
{
str = getFleetDelay(waitTime == -1 ? "" : waitTime);
if (typeof str == 'object' && !str)
return;
nt = parseInt(str, 10);
if (isNaN(nt))
{
fleetDelayError(0);
str = "";
}
else if (nt < 1)
{
fleetDelayError(1);
str = "";
}
else if (nt > 48)
{
fleetDelayError(2);
str = "";
}
}
waitTime = nt;
updateOrdersPage();
}
function cancelOrdersDelay()
{
waitTime = -1;
updateOrdersPage();
}
function removeOrdersDestination()
{
moveTo = -1;
updateOrdersPage();
}
function gotLocation(data) {
var l = data.split("\n");
var a, o;
a = l.shift().split('#');
moveToLoc = new FleetLocation(a.shift(),a.shift(),a.shift(),a.shift(),a.shift(),a.join('#'));
if (moveToLoc.opacity == 0) {
a = l.shift().split('#');
moveToLoc.details = new PlanetDetails(a.shift(),a.shift(),a.shift(),a.shift(),a.shift(),a.join('#'));
}
readingMoveLocation = false;
updateOrdersPage();
}
function setOrdersDestination() {
if (mapRemember && typeof sMovex == 'object') {
} else if (moveTo == -1) {
var ok = false;
if (typeof sMovex != 'object') {
dMapX = parseInt(sMovex,10);
dMapY = parseInt(sMovey,10);
ok = true;
} else {
if (orderFleets.length) {
var f = fleets.get(orderFleets[0]);
if (f) {
var fLoc = (f.orders.oType != 1 ? f.orders.loc : f.orders.cur);
dMapX = parseInt(fLoc.x, 10);
dMapY = parseInt(fLoc.y, 10);
ok = true;
}
}
}
if (! ok) {
if (myself.planets.length) {
dMapX = parseInt(myself.planets[0].x,10);
dMapY = parseInt(myself.planets[0].y,10);
} else {
var i = 0, j, k = allies.keys();
while (i < k.length)
{
var a = allies.get(k[i]);
if (!a.isMe && a.planets.length)
{
dMapX = parseInt(a.planets[0].x,10);
dMapY = parseInt(a.planets[0].y,10);
break;
}
i++;
}
if (i == k.length)
dMapX = dMapY = 0;
}
}
} else {
dMapX = parseInt(moveToLoc.x,10);
dMapY = parseInt(moveToLoc.y,10);
}
newDest = moveTo;
mapCType = 0;
drawDestinationSelection();
if (!map.containsKey(dMapX + ';' + dMapY))
{
loadingMap = true;
x_getMapData(dMapX, dMapY, gotMapData);
}
else
{
loadingMap = false;
updateDestinationSelection();
}
}
function gotMapData(data)
{
if (data == "ERR")
alertMap();
else
{
var l = data.split('\n');
var a = l.shift().split("#"), i;
dMapX = parseInt(a[0], 10); dMapY = parseInt(a[1], 10);
var system = new MapSystem(dMapX, dMapY, a[2], a[3] == '1');
for (i=0;i<6;i++)
{
if (system.opacity != -1)
{
a = l.shift().split('#');
var loc = new MapLocation(a.shift(), dMapX, dMapY, i+1, a.shift(), a.shift(), a.join('#'));
system.locations.push(loc);
map.put("p" + loc.id, loc);
map.put("pn-" + loc.name.toLowerCase(), loc);
}
else
system.locations.push(null);
}
map.put(dMapX + ";" + dMapY, system);
}
updateDestinationSelection();
loadingMap = false;
}
function updateDestinationSelection() {
updateDestLine();
if (typeof sMovex == 'object') {
drawGalacticMap();
} else {
drawSystemMap();
}
}
function updateDestLine()
{
if (newDest == -1)
document.getElementById('cursel').innerHTML = noSelection;
else
{
var d = map.get("p" + newDest);
document.getElementById('cursel').innerHTML = d.name + " (<b>" + d.x + "," + d.y + "</b>," + d.orbit + ")";
}
}
function drawSystemMap() {
var sys = map.get(dMapX + ";" + dMapY);
var str = "<table class='smap'><tr><td class='sys" + sys.opacity + "'>";
var i;
for (i = 0; i < 6; i ++) {
var loc = sys.locations[i];
if (sys.opacity == 0) {
var img = (loc.color == 4) ? "prem_s" : ("pl/s/"+loc.id);
str += "<tr onClick='setDestination(" + loc.id
+ ")'><td class='mimg'><img class='mimg' alt='[P]' src='"
+ staticurl + '/beta5/pics/'+img+".png' /></td><td class='ptype" + loc.color + "'>" +
loc.name + '</td></tr>';
} else {
str += "<tr onClick='setDestination(" + loc.id + ")'><td class='ptype" + loc.color
+ "'>" + loc.name + "</td></tr>";
}
}
str += '</td></tr></table><p class="smapi">' + smapCoordTxt + '<b>' + dMapX + ' , ' + dMapY + '</b></p>';
if (sys.protection) {
str = '<span class="prot">' + str + '</span>';
}
document.getElementById('sdmap').innerHTML = str;
}
function drawGalacticMap()
{
var sys = map.get(dMapX + ";" + dMapY);
var op = sys.opacity == -1 ? 0 : sys.opacity;
var str = "<table class='gmap'><tr><td class='gmcor'>&nbsp;</td><td class='gmvm' onClick='moveMap(0,1)'>"
+ "<img src='"+staticurl+"/beta5/pics/up_"+color+".gif' alt='"+dirTxt[0]+"' /></td>"
+ "<td class='gmcor'>&nbsp;</td></tr><tr><td class='gmhm' onClick='moveMap(-1,0)'>"
+ "<img src='"+staticurl+"/beta5/pics/left_"+color+".gif' alt='"+dirTxt[1]+"' /></td>"
+ "<td class='sys"+op+"'>" + (sys.protection ? '<span class="prot">' : '')
+ "<table class='gmmap'>";
var i;
for (i=0;i<6;i++)
{
var loc = sys.locations[i];
if (loc && sys.opacity == 0)
{
var img = (loc.color == 4) ? "prem_s" : ("pl/s/"+loc.id);
str += "<tr onClick='setDestination("+loc.id+")'><td class='mimg'><img class='mimg' alt='[P]' src='"
+ staticurl + '/beta5/pics/'+img+".png' /></td><td class='ptype" + loc.color + "'>" +
loc.name + '</td></tr>';
}
else if (loc)
str += "<tr onClick='setDestination("+loc.id+")'><td class='ptype"+loc.color+"'>"+loc.name+"</td></tr>";
else
str += '<tr><td class="gmun">'+unchartedTxt+'</td></tr>';
}
str += "</table>" + (sys.protection ? '</span>' : '')
+ "</td><td class='gmhm' onClick='moveMap(1,0)'><img src='"+staticurl+"/beta5/pics/right_"
+color+".gif' alt='"+dirTxt[2]+"' /></td></tr><tr><td class='gmcor'>&nbsp;</td><td class='gmvm' onClick='"
+"moveMap(0,-1)'><img src='"+staticurl+"/beta5/pics/down_"+color+".gif' alt='"+dirTxt[3]+"' /></td>"
+"<td class='gmcor'>&nbsp;</td></tr></table>";
str += drawMapControls();
document.getElementById('sdmap').innerHTML = str;
}
function updateGalacticMap()
{
if (loadingMap)
return;
var e;
if (document.getElementById('mct0').checked)
{
var x = parseInt(document.getElementById('cx').value, 10);
var y = parseInt(document.getElementById('cy').value, 10);
mapCType = 0;
if (isNaN(x) || isNaN(y))
return
moveMapTo(x,y);
}
else if (document.getElementById('mct1').checked)
{
e = document.getElementById('mcpo');
var p = e.options[e.selectedIndex].value;
mapCType = 1;
if (p == 0)
return;
mapParm = p;
if (map.containsKey('p'+p))
{
var po = map.get('p'+p);
moveMapTo(parseInt(po.x,10), parseInt(po.y,10));
}
else
{
loadingMap = true;
x_moveMapToId(p, gotMapData);
}
}
else
{
e = document.getElementById('mcpn').value;
mapCType = 2;
if (e == "")
return;
mapParm = e;
if (map.containsKey('pn-'+e.toLowerCase()))
{
var po = map.get('pn-'+e.toLowerCase());
moveMapTo(parseInt(po.x,10), parseInt(po.y,10));
}
else
{
loadingMap = true;
x_moveMapToName(e, gotMapData);
}
}
}
function moveMap(dx,dy)
{
if (loadingMap)
return;
mapCType = 0;
moveMapTo(dMapX + dx, dMapY + dy);
}
function moveMapTo(nx, ny)
{
if (map.containsKey(nx + ';' + ny))
{
dMapX = nx; dMapY = ny;
drawGalacticMap();
}
else
{
loadingMap = true;
x_getMapData(nx, ny, gotMapData);
}
}
function setDestination(id)
{
if (id == newDest)
return;
newDest = id;
document.getElementById('sdok').disabled = (newDest == moveTo);
updateDestLine();
}
function confirmSetDestination()
{
moveTo = newDest;
if (locations.containsKey(moveTo))
moveToLoc = locations.get(moveTo);
else
moveToLoc = null;
cancelSetDestination();
}
function cancelSetDestination()
{
drawOrdersPage();
updateOrdersPage();
}
function viewTrajectory()
{
if (autoLock)
{
setTimeout('viewTrajectory()', 500);
return;
}
lockUpdate();
var i, f = null;
for (i=0;i<fDisp.length;i++)
if (fDisp[i].selected)
{
f = fDisp[i];
break;
}
if (!(f && f.orders.oType == 1))
{
unlockUpdate();
return;
}
onMainPage = false;
x_getFleetTrajectory(f.id, gotFleetTrajectory);
}
function gotFleetTrajectory(data)
{
if (data == "") {
alertServerError();
x_getFleetsList(parseMainData);
return;
}
var l = data.split('\n');
var a, hc = false;
a = l.shift().split('#');
fleetTrajectory = new FleetTrajectory(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
while (l.length)
{
a = l.shift().split('#');
fleetTrajectory.waypoints.push(new FleetWayPoint(
a.shift(), a.shift(), a.shift(), a.shift(), a.shift(), a.join('#')
));
}
drawFleetTrajectory();
}
function sellSelected()
{
if (autoLock)
{
setTimeout('sellSelected()', 500);
return;
}
lockUpdate();
sales = new Hashtable();
for (var i=0;i<fDisp.length;i++)
{
if (!fDisp[i].selected || fDisp[i].orders.oType != 0 || fDisp[i].orders.canMove != 'Y' || fDisp[i].mode == 1)
continue;
var s;
if (!sales.containsKey(fDisp[i].orders.locId))
{
s = new FleetSale(fDisp[i].orders.locId);
sales.put(s.id, s);
}
else
s = sales.get(fDisp[i].orders.locId);
s.fleets.push(fDisp[i]);
}
if (sales.isEmpty())
{
prepareUpdate();
x_getFleetsList(parseMainData);
}
onMainPage = false;
drawSellPage();
}
function drawSellPage()
{
drawSellLayout();
var k = sales.keys(), str = '';
k.sort(sortSalesKeys);
for (var i=0;i<k.length;i++)
str += sales.get(k[i]).drawForm();
document.getElementById('sflist').innerHTML = str;
for (var i=0;i<k.length;i++)
sales.get(k[i]).update();
drawSellLinks(false);
}
function checkAllSales()
{
var k = sales.keys(), str = '', v = true;
for (var i=0;v&&i<k.length;i++)
v = v && sales.get(k[i]).isValid;
drawSellLinks(v);
}
function cancelSale()
{
sales = null;
prepareUpdate();
x_getFleetsList(parseMainData);
}
function confirmSale()
{
var k = sales.keys(), l = new Array();
for (var i=0;i<k.length;i++)
{
var s = sales.get(k[i]), j, fids = new Array(), p = s.player;
p.replace(/[^A-Za-z0-9_\.\-\+@\/' ]/, ' ');
for (j=0;j<s.fleets.length;j++)
fids.push(s.fleets[j].id);
l.push(s.id + '#' + s.mode + '#' + s.expires + '#' + s.price + '#' + p + '#' + fids.join('!'));
}
x_sellFleets(l.join('*'), fleetsSold);
}
function fleetsSold(data)
{
if (data.indexOf('ERR#') == 0)
{
var l = data.split('#');
l.shift();
var ec = parseInt(l.shift(), 10);
// Remove fleets and sales if required
if (ec == 4)
{
while (l.length)
{
var sid = l.shift(), fl = '!' + l.shift() + '!';
var s = sales.get(sid);
if (!s)
continue;
var f = new Array();
for (var i=0;i<s.fleets.length;i++)
{
if (fl.indexOf('!' + s.fleets[i].id + '!') != -1)
continue;
f.push(s.fleets[i]);
}
if (f.length)
s.fleets[i] = f;
else
sales.remove(sid);
}
if (sales.isEmpty())
{
saleAlert(5, null);
cancelSale();
return;
}
saleAlert(4, null);
var k = sales.keys(), str = '';
k.sort(sortSalesKeys);
for (var i=0;i<k.length;i++)
str += sales.get(k[i]).drawForm();
document.getElementById('sflist').innerHTML = str;
for (var i=0;i<k.length;i++)
{
sales.get(k[i]).update();
sales.get(k[i]).validate();
}
}
else
saleAlert(ec, l.shift());
}
else
{
clearSelection();
prepareUpdate();
parseMainData(data);
}
}
function cancelSaleSelected()
{
if (autoLock)
{
setTimeout('cancelSaleSelected()', 500);
return;
}
lockUpdate();
var s = new Array();
for (i=0;i<fDisp.length;i++)
{
if (fDisp[i].selected)
s.push(fDisp[i].orders.saleId);
}
if (confirmCancelSale(s.length >1))
x_cancelSales(s.join('#'), salesCanceled);
else
unlockUpdate();
}
function salesCanceled(str)
{
if (str.indexOf('ERR#') == 0)
{
var l = str.split('#');
alertCancelSales(parseInt(l[1], 10));
unlockUpdate();
}
else
{
prepareUpdate();
parseMainData(str);
}
}
function viewSaleSelected()
{
if (autoLock)
{
setTimeout('viewSaleSelected()', 500);
return;
}
lockUpdate();
var id = null;
for (i=0;i<fDisp.length;i++)
if (fDisp[i].selected)
{
id = fDisp[i].orders.saleId;
break;
}
if (id)
x_getSaleDetails(id, gotSaleDetails);
else
unlockUpdate();
}
function gotSaleDetails(str) {
if (str == "") {
alertViewSale();
unlockUpdate();
}
else
{
var t = str.split('\n'), l = t[0].split('#');
onMainPage = false;
drawSaleDetails(l, t.length == 2 ? t[1] : null);
}
}
function lockUpdate()
{
clearTimeout(autoUpdate);
autoLock = true;
}
function unlockUpdate()
{
autoUpdate = setTimeout('mainDataUpdate()', 60000);
autoLock = false;
}
function clearSelection()
{
var i;
if (typeof fDisp != 'object')
return;
for (i=0;i<fDisp.length;i++)
{
if (onMainPage)
document.getElementById('fsel' + fDisp[i].id).checked = false;
fDisp[i].selected = false;
}
if (onMainPage)
updateActions();
}
function parseMainDataInternal(data)
{
var l = data.split('\n');
var i, a = l.shift().split('#');
var nAllies = a.shift(), nFleets = a.shift(), nPlanets = a.shift();
// Get page parameters
a = l.shift().split('#');
listLocations = a.shift(); listMode = a.shift(); fDispMode = a.shift(); alliesMode = a.shift();
// Get search parameters
a = l.shift().split('#');
sType = a.shift(); sText = a.join('#');
// Parse lists
parseAllies(l, nAllies);
var plist = parseFleets(l, nFleets);
parsePlanets(l, nPlanets, plist);
parsePlayers(l, plist);
// Create links between lists
linkMainData();
}
function parseMainData(data)
{
// Do the actual parsing
parseMainDataInternal(data);
// Display page
if (!onMainPage)
{
drawMainLayout();
if (navigator.userAgent.toLowerCase().indexOf("msie") != -1 && document.all && !(window.opera && document.getElementById)) {
var ff = document.getElementById('faframe');
ff.style.position = "absolute";
var r = document.documentElement ? document.documentElement : document.body, h = r.clientHeight;
r.onscroll = function () {
ff.style.top = (r.scrollTop + h - 32) + "px";
};
ff.style.top = (r.scrollTop + h - 32) + "px";
}
onMainPage = true;
}
applyFilters();
drawMainContents();
// Get ready to auto-update
unlockUpdate();
}
function parseMainDataMove(data)
{
// Do the actual parsing
parseMainDataInternal(data);
// Display page
autoLock = true;
onMainPage = false;
var r = document.documentElement ? document.documentElement : document.body;
r.onscroll = null;
guessOrders = true;
orderFleets = new Array();
moveToLoc = null; waitTime = -1;
drawOrdersPage();
updateOrdersPage();
}
function sortMapPList(ia, ib) {
var a = locations.get(ia), b = locations.get(ib);
var oa = allies.get(a.details.owner), ob = allies.get(b.details.owner);
var pa = players.get(a.details.owner), pb = players.get(b.details.owner);
return (a.details.owner == b.details.owner
? (a.x != b.x
? (parseInt(a.x, 10) - parseInt(b.x, 10))
: (a.y != b.y
? (parseInt(a.y, 10) - parseInt(b.y, 10))
: (parseInt(a.orbit, 10) - parseInt(b.orbit, 10))
))
: (oa.isMe ? -1 : (ob.isMe ? 1 : (pa.toLowerCase() > pb.toLowerCase() ? 1 : -1))));
}
function sortPPList(ia,ib) {
var a=ppList.get(ia).fleetLocation,b=ppList.get(ib).fleetLocation;
return (a.x!=b.x
?(parseInt(a.x,10)-parseInt(b.x,10))
:(a.y!=b.y
?(parseInt(a.y,10)-parseInt(b.y,10))
:(parseInt(a.orbit,10)-parseInt(b.orbit,10))
)
);
}
function sortAPList(ia,ib) {
var a=apList.get(ia).fleetLocation,b=apList.get(ib).fleetLocation;
return (a.details.owner==b.details.owner
?(a.x!=b.x
?(parseInt(a.x,10)-parseInt(b.x,10))
:(a.y!=b.y
?(parseInt(a.y,10)-parseInt(b.y,10))
:(parseInt(a.orbit,10)-parseInt(b.orbit,10))
)
):(players.get(a.details.owner).toLowerCase()>players.get(b.details.owner).toLowerCase()?1:-1));
}
function sortOPList(ia,ib)
{
var a=opList.get(ia).fleetLocation,b=opList.get(ib).fleetLocation;
return (a.x!=b.x
?(parseInt(a.x,10)-parseInt(b.x,10))
:(a.y!=b.y
?(parseInt(a.y,10)-parseInt(b.y,10))
:(parseInt(a.orbit,10)-parseInt(b.orbit,10))
)
);
}
function sortPlanetFleets(ia,ib)
{
var a=fleets.get(ia),b=fleets.get(ib);
return (a.owner == b.owner
? (parseInt(b.power,10)-parseInt(a.power,10))
: (a.owner == myself.id ? -1 : (b.owner == myself.id ? 1 :
(a.mode == 0 && b.mode == 1 ? -1 : (a.mode == 1 && b.mode == 0 ? 1 :
(players.get(a.owner).toLowerCase()>players.get(b.owner).toLowerCase() ? 1 : -1)
))
))
);
}
function sortMovingFleets(a,b)
{
return (a.owner == b.owner
? (a.orders.eta == b.orders.eta
? (parseInt(b.power,10)-parseInt(a.power,10))
: (parseInt(a.orders.eta,10)-parseInt(b.orders.eta,10))
) : (a.owner == myself.id ? -1 : (b.owner == myself.id ? 1 :
(players.get(a.owner).toLowerCase()>players.get(b.owner).toLowerCase() ? 1 : -1)
))
);
}
function sortWaitingFleets(a,b)
{
return (a.owner == b.owner
? (a.orders.left == b.orders.left
? (parseInt(b.power,10)-parseInt(a.power,10))
: (parseInt(a.orders.left,10)-parseInt(b.orders.left,10))
) : (a.owner == myself.id ? -1 : (b.owner == myself.id ? 1 :
(players.get(a.owner).toLowerCase()>players.get(b.owner).toLowerCase() ? 1 : -1)
))
);
}
function sortOrderFleets(ia,ib)
{
var a=fleets.get(ia),b=fleets.get(ib);
return (a.owner == b.owner
? (parseInt(b.power,10)-parseInt(a.power,10))
: (a.owner == myself.id ? -1 : (b.owner == myself.id ? 1 :
(players.get(a.owner).toLowerCase()>players.get(b.owner).toLowerCase() ? 1 : -1)
))
);
}
function sortAvailFleets(a,b)
{
return (a.owner == b.owner
? (a.orders.oType == b.orders.oType && a.mode == b.mode
? (parseInt(b.power,10)-parseInt(a.power,10))
: (a.orders.oType * 2 + parseInt(a.mode,10) - b.orders.oType * 2 - parseInt(b.mode,10))
) : (a.owner == myself.id ? -1 : (b.owner == myself.id ? 1 :
(players.get(a.owner).toLowerCase()>players.get(b.owner).toLowerCase() ? 1 : -1)
))
);
}
function sortSalesKeys(ia,ib)
{
var a=locations.get(ia),b=locations.get(ib);
return (a.x!=b.x
?(parseInt(a.x,10)-parseInt(b.x,10))
:(a.y!=b.y
?(parseInt(a.y,10)-parseInt(b.y,10))
:(parseInt(a.orbit,10)-parseInt(b.orbit,10))
));
}