// ==UserScript==
// @id iitc-plugin-scoreboard@vita10gy
// @name IITC plugin: show a localized scoreboard.
// @version 0.1.6.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
// @description [@@BUILDNAME@@-@@BUILDDATE@@] A localized scoreboard.
// @include https://www.ingress.com/intel*
// @include http://www.ingress.com/intel*
// @match https://www.ingress.com/intel*
// @match http://www.ingress.com/intel*
// ==/UserScript==
function wrapper() {
// ensure plugin framework is there, even if iitc is not yet loaded
if(typeof window.plugin !== 'function') window.plugin = function() {};
// PLUGIN START ////////////////////////////////////////////////////////
// use own namespace for plugin
window.plugin.scoreboard = function() {};
window.plugin.scoreboard.scores = {};
window.plugin.scoreboard.playerGuids = new Array();
window.plugin.scoreboard.resetTeam = function(team) {
var scores = window.plugin.scoreboard.scores['team'];
scores[team] = {};
scores[team]['mu'] = 0;
scores[team]['count_fields'] = 0;
scores[team]['count_links'] = 0;
scores[team]['count_portals'] = 0;
scores[team]['count_resonators'] = 0;
scores[team]['link_length'] = 0;
scores[team]['field_area'] = 0;
scores[team]['largest'] = {};
};
window.plugin.scoreboard.initPlayer = function(player, team) {
var scores = window.plugin.scoreboard.scores['player'];
if(scores[player] === undefined) {
scores[player] = {};
scores[player]['team'] = team;
scores[player]['mu'] = 0;
scores[player]['count_fields'] = 0;
scores[player]['count_links'] = 0;
scores[player]['count_portals'] = 0;
scores[player]['count_resonators'] = 0;
scores[player]['link_length'] = 0;
scores[player]['field_area'] = 0;
// scores[player]['count_shields'] = 0;
scores[player]['largest'] = {};
window.plugin.scoreboard.playerGuids.push(player);
}
}
window.plugin.scoreboard.compileStats = function() {
var somethingInView = false;
window.plugin.scoreboard.playerGuids = new Array();
window.plugin.scoreboard.scores = {'team': {}, 'player': {}};
var scores = window.plugin.scoreboard.scores;
window.plugin.scoreboard.resetTeam(TEAM_RES);
window.plugin.scoreboard.resetTeam(TEAM_ENL);
$.each(window.fields, function(qk, val) {
var team = getTeam(val.options.data);
var player = val.options.data.creator.creatorGuid;
window.plugin.scoreboard.initPlayer(player,team);
// Google sends fields long since dead in the data. This makes sure it's still actually up.
if(window.portals[val.options.vertices.vertexA.guid] !== undefined ||
window.portals[val.options.vertices.vertexB.guid] !== undefined ||
window.portals[val.options.vertices.vertexC.guid] !== undefined ) {
var fieldArea = window.plugin.scoreboard.fieldArea(val);
somethingInView = true;
scores['team'][team]['mu'] += parseInt(val.options.data.entityScore.entityScore);
scores['player'][player]['mu'] += parseInt(val.options.data.entityScore.entityScore);
scores['team'][team]['count_fields']++;
scores['player'][player]['count_fields']++;
scores['team'][team]['field_area'] += fieldArea;
scores['player'][player]['field_area'] += fieldArea;
val.options.data.fieldArea = fieldArea;
var largestMu = scores['team'][team]['largest']['mu'];
if(largestMu === undefined || parseInt(largestMu.options.data.entityScore.entityScore) < parseInt(val.options.data.entityScore.entityScore)) {
largestMu = val;
}
scores['team'][team]['largest']['mu'] = largestMu;
//var largestMu = scores['player'][player]['largest']['mu'];
//if(largestMu === undefined || parseInt(largestMu.options.data.entityScore.entityScore) < parseInt(val.options.data.entityScore.entityScore)) {
// largestMu = val;
//}
//scores['player'][player]['largest']['mu'] = largestMu;
var largestArea = scores['team'][team]['largest']['field_area'];
if(largestArea === undefined || largestArea.options.data.fieldArea < val.options.data.fieldArea) {
largestArea = val;
}
scores['team'][team]['largest']['field_area'] = largestArea;
}
});
$.each(window.links, function(qk, link) {
somethingInView = true;
var team = getTeam(link.options.data);
var player = link.options.data.creator.creatorGuid;
window.plugin.scoreboard.initPlayer(player, team);
scores['team'][team]['count_links']++;
scores['player'][player]['count_links']++;
var linkLength = window.plugin.scoreboard.portalDistance(link.options.data.edge.destinationPortalLocation,link.options.data.edge.originPortalLocation);
scores['team'][team]['link_length'] += linkLength;
scores['player'][player]['link_length'] += linkLength;
var largestLink = scores['team'][team]['largest']['link'];
if(largestLink === undefined || largestLink.distance < linkLength) {
largestLink = {};
largestLink.distance = linkLength;
largestLink.player = player;
}
scores['team'][team]['largest']['link'] = largestLink;
//var largestLink = scores['player'][player]['largest']['link'];
//if(largestLink === undefined || largestLink < linkLength) {
// largestLink = linkLength;
//}
//scores['player'][player]['largest']['link'] = largestLink;
});
$.each(window.portals, function(qk, portal) {
somethingInView = true;
var team = getTeam(portal.options.details);
if(team !== TEAM_NONE) {
var player = portal.options.details.captured.capturingPlayerId;
window.plugin.scoreboard.initPlayer(player, team);
scores['team'][team]['count_portals']++;
scores['player'][player]['count_portals']++;
//$.each(portal.options.details.portalV2.linkedModArray, function(ind, mod) {
// if(mod !== null) {
// somethingInView = true;
// scores['team'][team]['count_shields']++;
// scores['player'][mod.installingUser]['count_shields']++;
// }
//});
$.each(portal.options.details.resonatorArray.resonators, function(ind, reso) {
if(reso !== null) {
somethingInView = true;
window.plugin.scoreboard.initPlayer(reso.ownerGuid, team);
scores['team'][team]['count_resonators']++;
scores['player'][reso.ownerGuid]['count_resonators']++;
}
});
}
});
return somethingInView;
};
window.plugin.scoreboard.percentSpan = function(percent, cssClass) {
var retVal = '';
if(percent > 0) {
retVal += '' + percent;
if(percent >= 7) { // anything less than this and the text doesnt fit in the span.
retVal += '%';
}
retVal += '';
}
return retVal;
};
window.plugin.scoreboard.teamTableRow = function(field,title) {
var scores = window.plugin.scoreboard.scores['team'];
var retVal = '
'
+ title
+ ' | '
+ window.digits(Math.round(scores[TEAM_RES][field]))
+ ' | '
+ window.digits(Math.round(scores[TEAM_ENL][field]))
+ ' | '
+ window.digits(Math.round(scores[TEAM_RES][field] + scores[TEAM_ENL][field]))
+ ' |
';
return retVal;
};
window.plugin.scoreboard.fieldInfo = function(field) {
var title = '';
var retVal = '';
if(field !== undefined) {
var portal = window.portals[field.options.vertices.vertexA.guid];
if(portal !== undefined) {
title = ' @' + portal.options.details.portalV2.descriptiveText.TITLE;
}
retVal = ''
+ window.digits(field.options.data.entityScore.entityScore)
+ ' - ' + window.getPlayerName(field.options.data.creator.creatorGuid)
+ '
';
} else {
retVal = 'N/A';
}
return retVal;
};
window.plugin.scoreboard.fieldInfoArea = function(field) {
var title = '';
var retVal = '';
if(field !== undefined) {
var portal = window.portals[field.options.vertices.vertexA.guid];
if(portal !== undefined) {
title = ' @' + portal.options.details.portalV2.descriptiveText.TITLE;
}
retVal = ''
+ window.digits(Math.round(field.options.data.fieldArea))
+ ' - ' + window.getPlayerName(field.options.data.creator.creatorGuid)
+ '
';
} else {
retVal = 'N/A';
}
return retVal;
};
window.plugin.scoreboard.playerTableRow = function(playerGuid) {
var scores = window.plugin.scoreboard.scores['player'];
var retVal = ''
+ window.getPlayerName(playerGuid);
+ ' | ';
$.each(['mu','count_fields','field_area','count_links','link_length','count_portals','count_resonators'], function(i, field) {
retVal += ''
+ window.digits(Math.round(scores[playerGuid][field]))
+ ' | ';
});
retVal += '
';
return retVal;
};
window.plugin.scoreboard.playerTable = function(sortBy) {
// Sort the playerGuid array by sortBy
window.plugin.scoreboard.playerGuids.sort(function(a, b) {
var playerA = window.plugin.scoreboard.scores['player'][a];
var playerB = window.plugin.scoreboard.scores['player'][b];
var retVal = 0;
if(sortBy === 'names') {
retVal = window.getPlayerName(a).toLowerCase() < window.getPlayerName(b).toLowerCase() ? -1 : 1;
} else {
retVal = playerB[sortBy] - playerA[sortBy];
}
return retVal;
});
var sort = window.plugin.scoreboard.playerTableSort;
var scoreHtml = ''
+ 'Player | '
+ 'Mu | '
+ 'Field # | '
+ 'Field (km²) | '
+ 'Link # | '
+ 'Link (m) | '
+ 'Portals | '
+ 'Resonators |
';
$.each(window.plugin.scoreboard.playerGuids, function(index, guid) {
scoreHtml += window.plugin.scoreboard.playerTableRow(guid);
});
scoreHtml += '
';
return scoreHtml;
}
// A little helper functon so the above isn't so messy
window.plugin.scoreboard.playerTableSort = function(name, by) {
var retVal = 'data-sort="' + name + '"';
if(name === by) {
retVal += ' class="sorted"';
}
return retVal;
};
window.plugin.scoreboard.display = function() {
var somethingInView = window.plugin.scoreboard.compileStats();
var scores = window.plugin.scoreboard.scores;
var resMu = scores['team'][TEAM_RES]['mu'];
var enlMu = scores['team'][TEAM_ENL]['mu'];
var scoreHtml = '';
if(somethingInView) {
if(resMu + enlMu > 0) {
var resMuPercent = Math.round((resMu / (resMu + enlMu)) * 100);
scoreHtml += ''
+ window.plugin.scoreboard.percentSpan(resMuPercent, 'res')
+ window.plugin.scoreboard.percentSpan(100-resMuPercent, 'enl')
+ '
';
}
scoreHtml += ''
+ ' | Resistance | Enlightened | Total |
'
+ window.plugin.scoreboard.teamTableRow('mu','Mu')
+ window.plugin.scoreboard.teamTableRow('count_fields','Field #')
+ window.plugin.scoreboard.teamTableRow('field_area','Field (km²)')
+ window.plugin.scoreboard.teamTableRow('count_links','Link #')
+ window.plugin.scoreboard.teamTableRow('link_length','Link (m)')
+ window.plugin.scoreboard.teamTableRow('count_portals','Portals')
+ window.plugin.scoreboard.teamTableRow('count_resonators','Resonators')
+ '
';
scoreHtml += ''
+ ' | Resistance | Enlightened |
'
+ 'Largest Field (Mu) | '
+ window.plugin.scoreboard.fieldInfo(scores['team'][TEAM_RES]['largest']['mu'])
+ ' | '
+ window.plugin.scoreboard.fieldInfo(scores['team'][TEAM_ENL]['largest']['mu'])
+ ' |
'
+ 'Largest Field (km²) | '
+ window.plugin.scoreboard.fieldInfoArea(scores['team'][TEAM_RES]['largest']['field_area'])
+ ' | '
+ window.plugin.scoreboard.fieldInfoArea(scores['team'][TEAM_ENL]['largest']['field_area'])
+ ' |
'
+ 'Longest Link (m) | ';
if(scores['team'][TEAM_RES]['largest']['link'] === undefined) {
scoreHtml += 'N/A';
}
else {
scoreHtml += window.digits(Math.round(scores['team'][TEAM_RES]['largest']['link']['distance']))
+ ' - '
+ window.getPlayerName(scores['team'][TEAM_RES]['largest']['link']['player']);
}
scoreHtml += ' | ';
if(scores['team'][TEAM_ENL]['largest']['link'] === undefined) {
scoreHtml += 'N/A';
}
else {
scoreHtml += window.digits(Math.round(scores['team'][TEAM_ENL]['largest']['link']['distance']))
+ ' - '
+ window.getPlayerName(scores['team'][TEAM_ENL]['largest']['link']['player']);
}
scoreHtml += ' |
'
+ '
'
+ ''
+ window.plugin.scoreboard.playerTable('mu')
+ '
';
scoreHtml += 'Click on player table headers to sort by that column. '
+ 'Score is subject to portals available based on zoom level. '
+ 'If names are unresolved try again. For best results wait until updates are fully loaded.
';
} else {
scoreHtml += 'You need something in view.';
}
alert('' + scoreHtml + '
', true, function() {$(".ui-dialog").removeClass('ui-dialog-scoreboard');});
$(".ui-dialog").addClass('ui-dialog-scoreboard');
// Setup sorting
$(document).on('click', '#players table th', function() {
$('#players').html(window.plugin.scoreboard.playerTable($(this).data('sort')));
});
}
window.plugin.scoreboard.portalDistance = function(portalAE6Location, portalBE6Location) {
portalA = new L.LatLng(portalAE6Location.latE6 / 1E6, portalAE6Location.lngE6 / 1E6);
portalB = new L.LatLng(portalBE6Location.latE6 / 1E6, portalBE6Location.lngE6 / 1E6);
return (portalA.distanceTo(portalB));
}
window.plugin.scoreboard.fieldArea = function(field) {
var verts = field.options.vertices;
var sideA = window.plugin.scoreboard.portalDistance(verts.vertexA.location,verts.vertexB.location) / 1000;
var sideB = window.plugin.scoreboard.portalDistance(verts.vertexB.location,verts.vertexC.location) / 1000;
var sideC = window.plugin.scoreboard.portalDistance(verts.vertexC.location,verts.vertexA.location) / 1000;
// Heron's Formula;
var perimeter = sideA + sideB + sideC;
var s = perimeter/2;
return Math.sqrt(s*(s-sideA)*(s-sideB)*(s-sideC));
}
var setup = function() {
$('#toolbox').append(' Scoreboard');
$('head').append('');
}
// PLUGIN END //////////////////////////////////////////////////////////
if(window.iitcLoaded && typeof setup === 'function') {
setup();
} else {
if(window.bootPlugins)
window.bootPlugins.push(setup);
else
window.bootPlugins = [setup];
}
} // wrapper end
// inject code into site context
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ wrapper +')();'));
(document.body || document.head || document.documentElement).appendChild(script);