Merge branch 'to-push' of github.com:nexushoratio/ingress-intel-total-conversion into to-push
Conflicts: plugins/portal-defense.user.js plugins/show-linked-portals.user.js
This commit is contained in:
0
plugins/add-kml.user.js
Executable file → Normal file
0
plugins/add-kml.user.js
Executable file → Normal file
@ -1,942 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-ap-list@xelio
|
||||
// @name IITC plugin: AP List
|
||||
// @category Info
|
||||
// @category Deleted
|
||||
// @version 0.5.7.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] List portals by AP of either faction or by effective level. Other functions and controls please refer to the Userguide.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.apList = function() {
|
||||
};
|
||||
|
||||
window.plugin.apList.cachedPortals = {};
|
||||
window.plugin.apList.SIDE_FRIENDLY = 0;
|
||||
window.plugin.apList.SIDE_ENEMY = 1;
|
||||
window.plugin.apList.displaySide = window.plugin.apList.SIDE_ENEMY;
|
||||
window.plugin.apList.sides = new Array(2);
|
||||
window.plugin.apList.sortedPortals = new Array(2);
|
||||
window.plugin.apList.playerApGainFunc = new Array(2);
|
||||
|
||||
window.plugin.apList.SORT_BY_AP = 'AP';
|
||||
window.plugin.apList.SORT_BY_EL = 'EL';
|
||||
window.plugin.apList.sortBy = window.plugin.apList.SORT_BY_AP;
|
||||
window.plugin.apList.SORT_ASC = 1;
|
||||
window.plugin.apList.SORT_DESC = -1;
|
||||
window.plugin.apList.sortOptions = {};
|
||||
|
||||
window.plugin.apList.currentPage = [1,1];
|
||||
window.plugin.apList.totalPage = [1,1];
|
||||
window.plugin.apList.portalPerPage = 10;
|
||||
window.plugin.apList.sideLabelClass = {};
|
||||
window.plugin.apList.tableColumns = new Array(2);
|
||||
|
||||
window.plugin.apList.useCachedPortals = false;
|
||||
window.plugin.apList.cacheBounds;
|
||||
window.plugin.apList.cacheActiveZoomLevel;
|
||||
|
||||
window.plugin.apList.destroyPortalsGuid = new Array();
|
||||
|
||||
window.plugin.apList.portalLocationIndicator;
|
||||
window.plugin.apList.animTimeout;
|
||||
|
||||
// ENTRY POINT ///////////////////////////////////////////////////////////////////
|
||||
window.plugin.apList.handleUpdate = function() {
|
||||
if(!requests.isLastRequest('getThinnedEntitiesV4')) return;
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
// CONTENT GENERATION ////////////////////////////////////////////////////////////
|
||||
|
||||
// Generate html table from top portals
|
||||
window.plugin.apList.updatePortalTable = function(side) {
|
||||
var table = '<table id="ap-list-table">'
|
||||
+ '<thead>'
|
||||
+ plugin.apList.tableHeaderBuilder(side)
|
||||
+ '</thead>';
|
||||
|
||||
table += '<tbody>';
|
||||
var startingPortal = (plugin.apList.currentPage[side] - 1) * plugin.apList.portalPerPage;
|
||||
for(var i = startingPortal; i < startingPortal + plugin.apList.portalPerPage; i++) {
|
||||
var portal = plugin.apList.sortedPortals[side][i];
|
||||
table += plugin.apList.tableRowBuilder(side, portal);
|
||||
}
|
||||
table += '</tbody></table>';
|
||||
$('div#ap-list-table').html(table);
|
||||
|
||||
plugin.apList.updatePaginationControl();
|
||||
plugin.apList.updateStats();
|
||||
}
|
||||
|
||||
window.plugin.apList.tableHeaderBuilder = function(side) {
|
||||
var headerRow = '<tr>';
|
||||
|
||||
$.each(plugin.apList.tableColumns[side], function(ind, column) {
|
||||
var cssClass = column.headerTooltip ? (column.cssClass + ' help') : column.cssClass;
|
||||
var title = column.headerTooltip ? column.headerTooltip : '';
|
||||
var onclick = column.headerOnClick ? column.headerOnClick: '';
|
||||
var content = column.headerFunction ? column.headerFunction() : column.header;
|
||||
headerRow += '<td class="' + cssClass + '" '
|
||||
+ 'title="' + title + '" '
|
||||
+ 'onclick="' + onclick + '" '
|
||||
+ '>'
|
||||
+ content
|
||||
+ '</td>';
|
||||
});
|
||||
|
||||
headerRow += '</tr>';
|
||||
return headerRow;
|
||||
}
|
||||
|
||||
window.plugin.apList.tableRowBuilder = function(side,portal) {
|
||||
var row = "<tr>";
|
||||
|
||||
$.each(plugin.apList.tableColumns[side], function(ind, column) {
|
||||
var content = portal ? column.contentFunction(portal) : ' ';
|
||||
row += '<td class="' + column.cssClass + '">'
|
||||
+ content
|
||||
+ '</td>';
|
||||
});
|
||||
|
||||
row += '</tr>';
|
||||
return row;
|
||||
}
|
||||
|
||||
window.plugin.apList.getHeaderCheckbox = function() {
|
||||
var onClick = 'window.plugin.apList.clearDestroyPortals();';
|
||||
var content = '<div class="ap-list-checkbox-header" />'
|
||||
var div = plugin.apList.getCheckbox(onClick, null, content);
|
||||
return div;
|
||||
}
|
||||
|
||||
window.plugin.apList.getPortalDestroyCheckbox = function(portal) {
|
||||
// Change background color to border color if portal selected for destroy
|
||||
var addedClass = plugin.apList.destroyPortalIndex(portal.guid) >= 0
|
||||
? 'ap-list-checkbox-selected' : '';
|
||||
var onClick = 'window.plugin.apList.destroyPortal(\'' + portal.guid + '\');';
|
||||
var div = plugin.apList.getCheckbox(onClick, addedClass, null);
|
||||
return div;
|
||||
}
|
||||
|
||||
window.plugin.apList.getCheckbox = function(onClick, addedClass, content) {
|
||||
// 2 div for centering checkbox horizontally and vertically,
|
||||
// click event on outest div for people with not so good aiming
|
||||
var div = '<div class="ap-list-checkbox-outer" onclick="' + (onClick || '')+ '">'
|
||||
+ '<div class="ap-list-checkbox-inner ' + (addedClass || '') + '">'
|
||||
+ (content || '')
|
||||
+ '</div>'
|
||||
+ '</div>';
|
||||
return div;
|
||||
}
|
||||
|
||||
// Combine ap title and test
|
||||
window.plugin.apList.getPortalApText = function(portal) {
|
||||
var title = plugin.apList.getPortalApTitle(portal);
|
||||
return '<div class="help" title="' + title + '">' + digits(portal.playerApGain.totalAp) + '</div>';
|
||||
}
|
||||
|
||||
// Friendly portal will get resonator upgrade list, enemy
|
||||
// portal will get ap breakdown
|
||||
window.plugin.apList.getPortalApTitle = function(portal) {
|
||||
var t;
|
||||
var playerApGain = portal.playerApGain;
|
||||
if(plugin.apList.portalSide(portal) === plugin.apList.SIDE_FRIENDLY) {
|
||||
t = 'Deploy & Upgrade\n';
|
||||
|
||||
for(var i = 0; i < playerApGain.upgradedReso.length; i++) {
|
||||
var reso = playerApGain.upgradedReso[i];
|
||||
var apGain = (reso.level === 0) ? DEPLOY_RESONATOR : UPGRADE_ANOTHERS_RESONATOR;
|
||||
t += 'Resonator on ' + OCTANTS[reso.slot] + '\t' + reso.level + '->'
|
||||
+ reso.newLevel + '\t= ' + apGain + '\n';
|
||||
}
|
||||
|
||||
if(playerApGain.captureBonus > 0)
|
||||
t += 'Capture\t\t= ' + playerApGain.captureBonus + '\n';
|
||||
if(playerApGain.completionBonus > 0)
|
||||
t += 'Bonus\t\t= ' + playerApGain.completionBonus + '\n';
|
||||
|
||||
t += 'Sum: ' + digits(playerApGain.totalAp) + ' AP';
|
||||
} else {
|
||||
t = 'Destroy & Capture:\n'
|
||||
+ 'R:' + playerApGain.resoCount + ' L:' + playerApGain.linkCount + ' CF:' + playerApGain.fieldCount + '\n'
|
||||
+ 'Destroy AP\t=\t' + digits(playerApGain.destroyAp) + '\n'
|
||||
+ 'Capture AP\t=\t' + digits(playerApGain.captureAp) + '\n'
|
||||
+ 'Sum: ' + digits(playerApGain.totalAp) + ' AP';
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
window.plugin.apList.getPortalEffectiveLvText = function(portal) {
|
||||
var title = plugin.apList.getPortalEffectiveLvTitle(portal);
|
||||
return '<div class="help" title="' + title + '">' + portal.effectiveLevel.effectiveLevel.toFixed(1) + '</div>';
|
||||
}
|
||||
|
||||
window.plugin.apList.getPortalEffectiveLvTitle = function(portal) {
|
||||
var t = 'Effective energy:\t' + portal.effectiveLevel.effectiveEnergy + '\n'
|
||||
+ 'Effect of Shields:\t' + portal.effectiveLevel.effectOfShields + '\n'
|
||||
+ 'Effect of resos dist:\t' + portal.effectiveLevel.effectOfResoDistance + '\n'
|
||||
+ 'Origin Level:\t' + portal.effectiveLevel.originLevel;
|
||||
return t;
|
||||
}
|
||||
|
||||
// portal link - single click: select portal
|
||||
// double click: zoom to and select portal
|
||||
// hover: show address
|
||||
window.plugin.apList.getPortalLink = function(portal) {
|
||||
var latlng = [portal.locationE6.latE6/1E6, portal.locationE6.lngE6/1E6].join();
|
||||
var jsSingleClick = 'window.plugin.apList.selectPortal(\''+portal.guid+'\');return false';
|
||||
var jsDoubleClick = 'window.zoomToAndShowPortal(\''+portal.guid+'\', ['+latlng+']);return false';
|
||||
var perma = '/intel?latE6='+portal.locationE6.latE6
|
||||
+'&lngE6='+portal.locationE6.lngE6+'&z=17&pguid='+portal.guid;
|
||||
//Use Jquery to create the link, which escape characters in TITLE and ADDRESS of portal
|
||||
var a = $('<a>',{
|
||||
"class": 'help',
|
||||
text: portal.portalV2.descriptiveText.TITLE,
|
||||
title: portal.portalV2.descriptiveText.ADDRESS,
|
||||
href: perma,
|
||||
onClick: jsSingleClick,
|
||||
onDblClick: jsDoubleClick
|
||||
})[0].outerHTML;
|
||||
|
||||
var divClass = plugin.apList.destroyPortalIndex(portal.guid) >= 0
|
||||
? 'ap-list-link ap-list-link-selected'
|
||||
: 'ap-list-link';
|
||||
var div = '<div class="' + divClass + '">'+a+'</div>';
|
||||
return div;
|
||||
}
|
||||
|
||||
window.plugin.apList.updatePaginationControl = function() {
|
||||
$('#ap-list-current-p').html(plugin.apList.currentPage[plugin.apList.displaySide]);
|
||||
$('#ap-list-total-p').html(plugin.apList.totalPage[plugin.apList.displaySide]);
|
||||
}
|
||||
|
||||
window.plugin.apList.updateStats = function() {
|
||||
var destroyPortals = plugin.apList.destroyPortalsGuid.length;
|
||||
if(destroyPortals === 0) {
|
||||
title = 'Stats';
|
||||
} else {
|
||||
var destroyAP = 0;
|
||||
var averageEL = 0;
|
||||
$.each(plugin.apList.destroyPortalsGuid, function(ind,guid) {
|
||||
destroyAP += plugin.apList.cachedPortals[guid].playerApGain.totalAp;
|
||||
averageEL += plugin.apList.cachedPortals[guid].effectiveLevel.effectiveLevel;
|
||||
});
|
||||
averageEL = Math.round(averageEL / destroyPortals * 10) / 10;
|
||||
|
||||
var title = 'Stats\n'
|
||||
+ 'Selected portal(s)\t=\t' + destroyPortals + '\n'
|
||||
+ 'Total AP\t=\t' + destroyAP + '\n'
|
||||
+ 'Average EL\t=\t' + averageEL;
|
||||
}
|
||||
|
||||
$('#ap-list-misc-info').attr('title', title);
|
||||
}
|
||||
|
||||
// MAIN LOGIC FUNCTIONS //////////////////////////////////////////////////////////
|
||||
|
||||
// Loop through portals and get playerApGain, then put in sortedPortals by side and sort them by AP.
|
||||
window.plugin.apList.updateSortedPortals = function() {
|
||||
plugin.apList.sortedPortals[plugin.apList.SIDE_FRIENDLY] = new Array();
|
||||
plugin.apList.sortedPortals[plugin.apList.SIDE_ENEMY] = new Array();
|
||||
|
||||
// Make a backup of cachedPortals with shallow copy
|
||||
// If cache is not enabled, empty cachedPortals. In following
|
||||
// "$.each" loop, the backup portal will copy back into
|
||||
// cachedPortals if it exist in "window.portals"" and didn't change.'
|
||||
var oldcachedPortal = $.extend({},plugin.apList.cachedPortals);
|
||||
if(!plugin.apList.useCachedPortals)
|
||||
plugin.apList.cachedPortals = {};
|
||||
|
||||
$.each(window.portals, function(key, value) {
|
||||
var portal = value.options.details;
|
||||
var cachedPortal = oldcachedPortal[key];
|
||||
// If portal is changed, update playerApGain with latest
|
||||
// information
|
||||
if(!cachedPortal
|
||||
|| value.timestamp !== cachedPortal.timestamp
|
||||
|| plugin.apList.isFieldsChanged(portal.portalV2.linkedFields, cachedPortal.portalV2.linkedFields)) {
|
||||
// Shallow copy portal detail to cachedPortal
|
||||
cachedPortal = $.extend({}, portal);
|
||||
var side = plugin.apList.portalSide(portal);
|
||||
var getApGainFunc = plugin.apList.playerApGainFunc[side];
|
||||
// Assign playerApGain and guid to cachedPortal
|
||||
cachedPortal.timestamp = value.timestamp
|
||||
cachedPortal.playerApGain = getApGainFunc(portal);
|
||||
cachedPortal.effectiveLevel = plugin.apList.getEffectiveLevel(portal);
|
||||
cachedPortal.guid = value.options.guid;
|
||||
}
|
||||
plugin.apList.cachedPortals[key] = cachedPortal;
|
||||
});
|
||||
|
||||
// Add all portals to sortedPortals by side and sort sortedPortals by AP
|
||||
$.each(plugin.apList.cachedPortals, function(key, portal) {
|
||||
var side = plugin.apList.portalSide(portal);
|
||||
plugin.apList.sortedPortals[side].push(portal);
|
||||
});
|
||||
$.each(plugin.apList.sides, function(ind, side) {
|
||||
plugin.apList.sortedPortals[side].sort(plugin.apList.comparePortal);
|
||||
});
|
||||
|
||||
// Modify sortedPortals if any portal selected for destroy
|
||||
plugin.apList.handleDestroyPortal();
|
||||
// Update pagination control data
|
||||
plugin.apList.updateTotalPages();
|
||||
}
|
||||
|
||||
// This function will make AP gain of field and link only count once if
|
||||
// one of the connected portal is selected for destroy
|
||||
window.plugin.apList.handleDestroyPortal = function() {
|
||||
if(plugin.apList.destroyPortalsGuid.length === 0) return;
|
||||
|
||||
var enemy = window.plugin.apList.SIDE_ENEMY;
|
||||
var destroyedLinks = {};
|
||||
var destroyedFields = {};
|
||||
|
||||
// Clean up portal selected for destroy, remove from destroyPortalsGuid
|
||||
// if portal not exist or change to friendly side
|
||||
plugin.apList.destroyPortalsGuid = $.grep(plugin.apList.destroyPortalsGuid, function(portalGuid,ind) {
|
||||
var portal = plugin.apList.cachedPortals[portalGuid];
|
||||
if(!portal || plugin.apList.portalSide(portal) !== enemy) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Loop through portals from highest AP to lowest AP, matching links and fields to the
|
||||
// portal only if the portal is selected for destroy and have highest AP.
|
||||
// Matching info stores in "destroyedLinks" and "destroyedFields"
|
||||
$.each(plugin.apList.sortedPortals[enemy], function(ind, portal) {
|
||||
if(plugin.apList.destroyPortalIndex(portal.guid) < 0) return true;
|
||||
|
||||
$.each(portal.portalV2.linkedEdges || [], function(ind,link) {
|
||||
// Skip if the link already matched with a portal
|
||||
if(destroyedLinks[link.edgeGuid]) return true;
|
||||
belongTo = {portalGuid: portal.guid};
|
||||
destroyedLinks[link.edgeGuid] = belongTo;
|
||||
});
|
||||
$.each(portal.portalV2.linkedFields || [], function(ind,field) {
|
||||
// Skip if the field already matched with a portal
|
||||
if(destroyedFields[field]) return true;
|
||||
belongTo = {portalGuid: portal.guid};
|
||||
destroyedFields[field] = belongTo;
|
||||
});
|
||||
});
|
||||
|
||||
// Remove the link and field which was matched with another portal
|
||||
var getApGainFunc = plugin.apList.playerApGainFunc[enemy];
|
||||
$.each(plugin.apList.sortedPortals[enemy], function(ind, portal) {
|
||||
// Filter out links which was matched with another portal
|
||||
var newLinkedEdges = $.grep(portal.portalV2.linkedEdges || [], function(link,ind) {
|
||||
if(!destroyedLinks[link.edgeGuid]) return true;
|
||||
return (destroyedLinks[link.edgeGuid].portalGuid === portal.guid);
|
||||
});
|
||||
// Filter out fields which was matched with another portal
|
||||
var newLinkedFields = $.grep(portal.portalV2.linkedFields || [], function(field,ind) {
|
||||
if(!destroyedFields[field]) return true;
|
||||
return (destroyedFields[field].portalGuid === portal.guid);
|
||||
});
|
||||
|
||||
// Skip modifying portal if no link and field changed
|
||||
if(newLinkedEdges.length === (portal.portalV2.linkedEdges || []).length
|
||||
&& newLinkedFields.length === (portal.portalV2.linkedFields || []).length)
|
||||
return true;
|
||||
|
||||
// Clone the portal with deep copy to avoid modifying original data in cachedPortal
|
||||
var newPortal = $.extend(true, {}, portal);
|
||||
// Assign new links and fields and calculate new playerApGain
|
||||
if(portal.portalV2.linkedEdges) newPortal.portalV2.linkedEdges = newLinkedEdges;
|
||||
if(portal.portalV2.linkedFields) newPortal.portalV2.linkedFields = newLinkedFields;
|
||||
newPortal.playerApGain = getApGainFunc(newPortal);
|
||||
|
||||
plugin.apList.sortedPortals[enemy][ind] = newPortal;
|
||||
});
|
||||
|
||||
// Sorting portals with updated AP
|
||||
plugin.apList.sortedPortals[enemy].sort(plugin.apList.comparePortal);
|
||||
}
|
||||
|
||||
window.plugin.apList.updateTotalPages = function() {
|
||||
$.each(plugin.apList.sortedPortals, function(side, portals) {
|
||||
plugin.apList.totalPage[side] = Math.max(Math.ceil(portals.length / plugin.apList.portalPerPage), 1);
|
||||
plugin.apList.currentPage[side] = Math.min(plugin.apList.totalPage[side], plugin.apList.currentPage[side]);
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.apList.isFieldsChanged = function(a,b) {
|
||||
// http://stackoverflow.com/questions/1773069/using-jquery-to-compare-two-arrays
|
||||
return $(a).not(b).get().length === 0 && $(b).not(a).get().length === 0;;
|
||||
}
|
||||
|
||||
window.plugin.apList.portalSide = function(portal) {
|
||||
return (portal.controllingTeam.team === PLAYER.team
|
||||
|| portal.controllingTeam.team === 'NEUTRAL')
|
||||
? plugin.apList.SIDE_FRIENDLY
|
||||
: plugin.apList.SIDE_ENEMY;
|
||||
}
|
||||
|
||||
// Get AP of friendly portal
|
||||
window.plugin.apList.getDeployOrUpgradeApGain = function(d) {
|
||||
var playerResoCount = new Array(MAX_PORTAL_LEVEL + 1);
|
||||
var otherReso = new Array();
|
||||
var totalAp = 0;
|
||||
var upgradedReso = new Array();
|
||||
|
||||
var deployCount = 0;
|
||||
var upgradedCount = 0;
|
||||
|
||||
var captureBonus = 0;
|
||||
var completionBonus = 0;
|
||||
|
||||
// loop through reso slot and find empty reso, deployed
|
||||
// by others(only level lower than player level) or by player.
|
||||
for(var i = 0; i < 8; i++) {
|
||||
var reso = d.resonatorArray.resonators[i];
|
||||
// Empty reso
|
||||
if(!reso) {
|
||||
otherReso.push({slot: i, level: 0});
|
||||
continue;
|
||||
}
|
||||
// By player
|
||||
if(reso.ownerGuid === window.PLAYER.guid) {
|
||||
playerResoCount[reso.level] = (playerResoCount[reso.level] || 0) + 1;
|
||||
continue;
|
||||
}
|
||||
// By others and level lower than player
|
||||
if(reso.level < window.PLAYER.level) {
|
||||
otherReso.push(reso);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort others reso low to high, last reso in otherReso get upgrade first.
|
||||
otherReso.sort(function(a, b) {return a.level - b.level;});
|
||||
|
||||
// Find out available count of reso for each level
|
||||
for(var i = window.PLAYER.level; i > 0 && otherReso.length > 0; i--) {
|
||||
var availableCount = MAX_RESO_PER_PLAYER[i] - (playerResoCount[i] || 0);
|
||||
// Loop through lower level reso of others and add to result
|
||||
while(availableCount > 0 && otherReso.length > 0) {
|
||||
var targetReso = otherReso.pop();
|
||||
// Can only upgrade lower level reso
|
||||
if(targetReso.level >= i)
|
||||
continue;
|
||||
// Add upgraded reso to result
|
||||
targetReso.newLevel = i;
|
||||
upgradedReso.push(targetReso);
|
||||
// Counting upgrade or deploy
|
||||
(targetReso.level === 0) ? deployCount++ : upgradedCount++;
|
||||
|
||||
availableCount--;
|
||||
}
|
||||
}
|
||||
|
||||
if(deployCount > 0) completionBonus = COMPLETION_BONUS;
|
||||
if(deployCount === 8) captureBonus = CAPTURE_PORTAL;
|
||||
|
||||
totalAp = deployCount * DEPLOY_RESONATOR
|
||||
+ upgradedCount * UPGRADE_ANOTHERS_RESONATOR
|
||||
+ captureBonus
|
||||
+ completionBonus;
|
||||
|
||||
return {
|
||||
captureBonus: captureBonus,
|
||||
completionBonus: completionBonus,
|
||||
totalAp: totalAp,
|
||||
upgradedReso: upgradedReso
|
||||
};
|
||||
}
|
||||
|
||||
window.plugin.apList.getAttackApGain = function(d) {
|
||||
var resoCount = 0;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if (!reso)
|
||||
return true;
|
||||
resoCount += 1;
|
||||
});
|
||||
|
||||
var linkCount = d.portalV2.linkedEdges ? d.portalV2.linkedEdges.length : 0;
|
||||
var fieldCount = d.portalV2.linkedFields ? d.portalV2.linkedFields.length : 0;
|
||||
|
||||
var resoAp = resoCount * DESTROY_RESONATOR;
|
||||
var linkAp = linkCount * DESTROY_LINK;
|
||||
var fieldAp = fieldCount * DESTROY_FIELD;
|
||||
var destroyAp = resoAp + linkAp + fieldAp;
|
||||
var captureAp = CAPTURE_PORTAL + 8 * DEPLOY_RESONATOR + COMPLETION_BONUS;
|
||||
var totalAp = destroyAp + captureAp;
|
||||
|
||||
return {
|
||||
totalAp: totalAp,
|
||||
destroyAp: destroyAp,
|
||||
captureAp: captureAp,
|
||||
resoCount: resoCount,
|
||||
linkCount: linkCount,
|
||||
fieldCount: fieldCount
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.apList.getEffectiveLevel = function(portal) {
|
||||
var effectiveEnergy = 0;
|
||||
var effectiveLevel = 0;
|
||||
|
||||
var resosStats = plugin.apList.getResonatorsStats(portal);
|
||||
|
||||
|
||||
// Calculate effective energy
|
||||
|
||||
var effectOfShields = plugin.apList.getShieldsEffect(portal);
|
||||
|
||||
// If avgResoDistance is 0, 8 resonators in the same place and can be treated as 1 resonator.
|
||||
// So the minimum effect of resonator distance is 1/8
|
||||
var effectOfResoDistance = (1 + (resosStats.avgResoDistance / HACK_RANGE) * 7 ) / 8;
|
||||
|
||||
effectiveEnergy = resosStats.currentEnergy * effectOfShields * effectOfResoDistance;
|
||||
|
||||
// Calculate effective level
|
||||
for(var i = MAX_PORTAL_LEVEL; i >= 0; i--) {
|
||||
var baseLevel = i;
|
||||
var baseLevelEnergy = RESO_NRG[baseLevel] * 8;
|
||||
if(effectiveEnergy >= baseLevelEnergy) {
|
||||
var energyToNextLevel = baseLevel === MAX_PORTAL_LEVEL
|
||||
? baseLevelEnergy - RESO_NRG[MAX_PORTAL_LEVEL - 1] * 8 // Extrapolate
|
||||
: RESO_NRG[baseLevel + 1] * 8 - baseLevelEnergy; // Interpolate
|
||||
|
||||
var additionalLevel = (effectiveEnergy - baseLevelEnergy) / energyToNextLevel;
|
||||
effectiveLevel = baseLevel + additionalLevel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Account for damage do to player by portal
|
||||
var portalLevel = parseInt(getPortalLevel(portal));
|
||||
if(effectiveLevel < portalLevel) {
|
||||
var energyPect = resosStats.currentEnergy / resosStats.totalEnergy;
|
||||
effectiveLevel = effectiveLevel * (1-energyPect) + portalLevel * energyPect;
|
||||
}
|
||||
|
||||
return {
|
||||
effectiveLevel: Math.round(effectiveLevel * 10) / 10,
|
||||
effectiveEnergy: parseInt(effectiveEnergy),
|
||||
effectOfShields: Math.round(effectOfShields * 100) / 100,
|
||||
effectOfResoDistance: Math.round(effectOfResoDistance * 100) / 100,
|
||||
originLevel: portalLevel
|
||||
};
|
||||
}
|
||||
|
||||
window.plugin.apList.getResonatorsStats = function(portal) {
|
||||
var totalEnergy = 0;
|
||||
var currentEnergy = 0;
|
||||
var avgResoDistance = 0;
|
||||
|
||||
$.each(portal.resonatorArray.resonators, function(ind, reso) {
|
||||
if (!reso)
|
||||
return true;
|
||||
totalEnergy += RESO_NRG[reso.level];
|
||||
currentEnergy += reso.energyTotal;
|
||||
avgResoDistance += (reso.distanceToPortal / 8);
|
||||
});
|
||||
return {
|
||||
totalEnergy: totalEnergy,
|
||||
currentEnergy: currentEnergy,
|
||||
avgResoDistance: avgResoDistance};
|
||||
}
|
||||
|
||||
window.plugin.apList.getShieldsEffect = function(portal) {
|
||||
// shield effect: each shield's mitigation value is assumed to be the percentage of the damage it will absorb
|
||||
// the rest of the damage gets through to the next shield, and so on.
|
||||
// so, to calculate the total protection, we multiply the fractions of damage allowed through each shield
|
||||
// to get a final figure of how much damage gets through
|
||||
// e.g.
|
||||
// one shield: mitigation 10 - lets 90% of the damage through
|
||||
// two shields: mitigation 20 and 30 - first one lets 80% through, second 70% of the remaining
|
||||
// so final amount let through = 0.8 * 0.7 = 0.56 = 56% damage let through
|
||||
// four shields: mitigation 30 - 70% through each = 0.7 * 0.7 * 0.7 * 0.7 = 0.24 = 24% damage gets through all four
|
||||
|
||||
var shieldsEffect = 1;
|
||||
$.each(portal.portalV2.linkedModArray, function(ind, mod) {
|
||||
if(!mod)
|
||||
return true;
|
||||
if(!mod.stats.MITIGATION)
|
||||
return true;
|
||||
shieldsEffect *= (1 - parseInt(mod.stats.MITIGATION)/100.0);
|
||||
});
|
||||
return shieldsEffect;
|
||||
}
|
||||
|
||||
// For using in .sort(func) of sortedPortals
|
||||
// Use options in plugin.apList.sortOptions. Each type of sortBy has
|
||||
// array of options. Option consist of an ordering and a property chain.
|
||||
//
|
||||
// Sorting done by loop through the options, get the property by
|
||||
// property chain of each option, compare the property of two object
|
||||
// with the ordering of option and return the result when the first
|
||||
// difference is found.
|
||||
window.plugin.apList.comparePortal = function(a,b) {
|
||||
var result = 0;
|
||||
var options = plugin.apList.sortOptions[plugin.apList.sortBy];
|
||||
|
||||
$.each(options, function(indO, option) {
|
||||
var aProperty = a;
|
||||
var bProperty = b;
|
||||
// Walking down the chain
|
||||
$.each(option.chain, function(indPN, propertyName) {
|
||||
aProperty = aProperty[propertyName];
|
||||
bProperty = bProperty[propertyName];
|
||||
});
|
||||
// compare next property if equal
|
||||
if(aProperty === bProperty) return true;
|
||||
|
||||
result = (aProperty > bProperty ? 1 : -1) * option.order;
|
||||
return false;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FEATURE TOGGLES AND INTERACTION HANDLER ///////////////////////////////////////
|
||||
|
||||
window.plugin.apList.enableCache = function() {
|
||||
plugin.apList.useCachedPortals = true;
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
window.plugin.apList.disableCache = function() {
|
||||
plugin.apList.useCachedPortals = false;
|
||||
plugin.apList.cachedPortals = {};
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
window.plugin.apList.selectPortal = function(guid) {
|
||||
// Add error catching to avoid following link of portal if error
|
||||
// occurred in renderPortalDetails or hooked plugin
|
||||
try {
|
||||
renderPortalDetails(guid);
|
||||
} catch(e) {
|
||||
console.error(e.message);
|
||||
console.log(e.stack);
|
||||
console.log('Skipping error in renderPortalDetails or hooked plugin')
|
||||
}
|
||||
plugin.apList.setPortalLocationIndicator(guid);
|
||||
}
|
||||
|
||||
window.plugin.apList.setPortalLocationIndicator = function(guid) {
|
||||
var portal = window.portals[guid];
|
||||
if(!portal) return;
|
||||
var startRadius = screen.availWidth / 2;
|
||||
var portalRadius = portal.options.radius;
|
||||
var latlng = portal.getLatLng();
|
||||
var property = {
|
||||
radius: startRadius,
|
||||
fill: false,
|
||||
color: COLOR_SELECTED_PORTAL,
|
||||
weight: 2,
|
||||
opacity: 1,
|
||||
portalRadius: portalRadius,
|
||||
clickable: false };
|
||||
|
||||
if(plugin.apList.portalLocationIndicator)
|
||||
map.removeLayer(plugin.apList.portalLocationIndicator);
|
||||
if(plugin.apList.animTimeout)
|
||||
clearTimeout(plugin.apList.animTimeout);
|
||||
plugin.apList.portalLocationIndicator = L.circleMarker(latlng, property).addTo(map);
|
||||
plugin.apList.animTimeout = setTimeout(plugin.apList.animPortalLocationIndicator,100);
|
||||
}
|
||||
|
||||
window.plugin.apList.animPortalLocationIndicator = function() {
|
||||
var radius = plugin.apList.portalLocationIndicator.options.radius;
|
||||
var portalRadius = plugin.apList.portalLocationIndicator.options.portalRadius
|
||||
if(radius > portalRadius) {
|
||||
var step = radius / 3;
|
||||
if(radius < 80) step = step / 3;
|
||||
var newRadius = plugin.apList.portalLocationIndicator.options.radius -= step;
|
||||
plugin.apList.portalLocationIndicator.setRadius(newRadius);
|
||||
if(plugin.apList.animTimeout)
|
||||
clearTimeout(plugin.apList.animTimeout);
|
||||
plugin.apList.animTimeout = setTimeout(plugin.apList.animPortalLocationIndicator,100);
|
||||
} else {
|
||||
map.removeLayer(plugin.apList.portalLocationIndicator);
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.apList.changePage = function(step, toEnd) {
|
||||
var side = plugin.apList.displaySide;
|
||||
var oldPage = plugin.apList.currentPage[side];
|
||||
|
||||
if(toEnd) {
|
||||
if(step < 0) plugin.apList.currentPage[side] = 1;
|
||||
if(step > 0) plugin.apList.currentPage[side] = plugin.apList.totalPage[side]
|
||||
} else {
|
||||
plugin.apList.currentPage[side] += step;
|
||||
if(plugin.apList.currentPage[side] < 1)
|
||||
plugin.apList.currentPage[side] = 1;
|
||||
if(plugin.apList.currentPage[side] > plugin.apList.totalPage[side])
|
||||
plugin.apList.currentPage[side] = plugin.apList.totalPage[side];
|
||||
}
|
||||
|
||||
if(plugin.apList.currentPage[side] !== oldPage)
|
||||
plugin.apList.updatePortalTable(side);
|
||||
}
|
||||
|
||||
window.plugin.apList.changeSorting = function(sortBy) {
|
||||
var oldSortBy = plugin.apList.sortBy;
|
||||
plugin.apList.sortBy = sortBy;
|
||||
if(plugin.apList.sortBy !== oldSortBy) {
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.apList.clearDestroyPortals = function() {
|
||||
plugin.apList.destroyPortalsGuid = new Array();
|
||||
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
window.plugin.apList.destroyPortal = function(guid) {
|
||||
// Add to destroyPortalsGuid if not yet added, remove if already added
|
||||
var portalIndex = plugin.apList.destroyPortalIndex(guid);
|
||||
if(portalIndex >= 0) {
|
||||
plugin.apList.destroyPortalsGuid.splice(portalIndex, 1);
|
||||
} else {
|
||||
plugin.apList.destroyPortalsGuid.push(guid);
|
||||
}
|
||||
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
// Return the index of portal in destroyPortalsGuid
|
||||
window.plugin.apList.destroyPortalIndex = function(guid) {
|
||||
return $.inArray(guid, plugin.apList.destroyPortalsGuid);
|
||||
}
|
||||
|
||||
// Change display table to friendly portals
|
||||
window.plugin.apList.displayFriendly = function() {
|
||||
plugin.apList.changeDisplaySide(plugin.apList.SIDE_FRIENDLY);
|
||||
}
|
||||
|
||||
// Change display table to enemy portals
|
||||
window.plugin.apList.displayEnemy = function() {
|
||||
plugin.apList.changeDisplaySide(plugin.apList.SIDE_ENEMY);
|
||||
}
|
||||
|
||||
window.plugin.apList.changeDisplaySide = function(side) {
|
||||
var isChange = (plugin.apList.displaySide !== side);
|
||||
var scrollTo = 0;
|
||||
if(isChange) {
|
||||
plugin.apList.displaySide = side;
|
||||
plugin.apList.updatePortalTable(side);
|
||||
plugin.apList.toggleSideLabel(side);
|
||||
scrollTo = $("#ap-list").position().top + $("#ap-list").outerHeight()
|
||||
- $("#sidebar").height() + $("#sidebar").scrollTop();
|
||||
}
|
||||
$('#sidebar').scrollTop(scrollTo);
|
||||
}
|
||||
|
||||
window.plugin.apList.toggleSideLabel = function(side) {
|
||||
$.each(plugin.apList.sides, function(ind,key) {
|
||||
var labelClass = plugin.apList.sideLabelClass[key];
|
||||
var opacity = (key === side) ? 1.0 : 0.5;
|
||||
$(labelClass).css("opacity", opacity);
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.apList.hideReloadLabel = function() {
|
||||
$('#ap-list-reload').hide();
|
||||
}
|
||||
|
||||
window.plugin.apList.showReloadLabel = function() {
|
||||
$('#ap-list-reload').show();
|
||||
}
|
||||
|
||||
// SETUP /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
window.plugin.apList.setupVar = function() {
|
||||
plugin.apList.sides[plugin.apList.SIDE_FRIENDLY] = plugin.apList.SIDE_FRIENDLY;
|
||||
plugin.apList.sides[plugin.apList.SIDE_ENEMY] = plugin.apList.SIDE_ENEMY;
|
||||
plugin.apList.playerApGainFunc[plugin.apList.SIDE_FRIENDLY]
|
||||
= plugin.apList.getDeployOrUpgradeApGain;
|
||||
plugin.apList.playerApGainFunc[plugin.apList.SIDE_ENEMY]
|
||||
= plugin.apList.getAttackApGain;
|
||||
plugin.apList.sideLabelClass[plugin.apList.SIDE_FRIENDLY]
|
||||
= "#ap-list-frd";
|
||||
plugin.apList.sideLabelClass[plugin.apList.SIDE_ENEMY]
|
||||
= "#ap-list-eny";
|
||||
plugin.apList.sortedPortals[plugin.apList.SIDE_FRIENDLY] = new Array();
|
||||
plugin.apList.sortedPortals[plugin.apList.SIDE_ENEMY] = new Array();
|
||||
}
|
||||
|
||||
window.plugin.apList.setupSorting = function() {
|
||||
var optionELAsc = {
|
||||
order: plugin.apList.SORT_ASC,
|
||||
chain: ['effectiveLevel','effectiveLevel']};
|
||||
var optionAPDesc = {
|
||||
order: plugin.apList.SORT_DESC,
|
||||
chain: ['playerApGain','totalAp']};
|
||||
var optionGuidDesc = {
|
||||
order: plugin.apList.SORT_DESC,
|
||||
chain: ['guid']};
|
||||
|
||||
// order by EL -> AP -> guid
|
||||
plugin.apList.sortOptions[plugin.apList.SORT_BY_EL] = [optionELAsc, optionAPDesc, optionGuidDesc];
|
||||
// order by AP -> EL -> guid
|
||||
plugin.apList.sortOptions[plugin.apList.SORT_BY_AP] = [optionAPDesc, optionELAsc, optionGuidDesc];
|
||||
}
|
||||
|
||||
// Setup table columns for header builder and row builder
|
||||
window.plugin.apList.setupTableColumns = function() {
|
||||
var enemyColumns = new Array();
|
||||
var friendlyColumns = new Array();
|
||||
|
||||
// AP and Eff. LV columns are same in enemy and friendly table
|
||||
var apColumn = {
|
||||
header: 'AP',
|
||||
headerOnClick: 'plugin.apList.changeSorting(plugin.apList.SORT_BY_AP);',
|
||||
headerTooltip: 'Click to sort by AP',
|
||||
cssClass: 'ap-list-td-ap',
|
||||
contentFunction: plugin.apList.getPortalApText
|
||||
};
|
||||
var effectiveLevelColumn = {
|
||||
header: 'EL',
|
||||
headerOnClick: 'plugin.apList.changeSorting(plugin.apList.SORT_BY_EL);',
|
||||
headerTooltip: 'Effective Level\nClick to sort by EL',
|
||||
cssClass: 'ap-list-td-eff-lv',
|
||||
contentFunction: plugin.apList.getPortalEffectiveLvText
|
||||
};
|
||||
|
||||
// Columns: Checkbox | Portal | AP | Eff. LV
|
||||
enemyColumns.push({
|
||||
headerFunction: plugin.apList.getHeaderCheckbox,
|
||||
headerTooltip: 'Unselect all',
|
||||
cssClass: 'ap-list-td-checkbox',
|
||||
contentFunction: plugin.apList.getPortalDestroyCheckbox
|
||||
});
|
||||
enemyColumns.push({
|
||||
header: 'Portal',
|
||||
cssClass: 'ap-list-td-link ap-list-td-link-eny',
|
||||
contentFunction: plugin.apList.getPortalLink
|
||||
});
|
||||
enemyColumns.push(apColumn);
|
||||
enemyColumns.push(effectiveLevelColumn);
|
||||
|
||||
// Columns: Portal | AP | Eff. LV
|
||||
friendlyColumns.push({
|
||||
header: 'Portal',
|
||||
cssClass: 'ap-list-td-link ap-list-td-link-frd',
|
||||
contentFunction: plugin.apList.getPortalLink
|
||||
});
|
||||
friendlyColumns.push(apColumn);
|
||||
friendlyColumns.push(effectiveLevelColumn);
|
||||
|
||||
plugin.apList.tableColumns[plugin.apList.SIDE_ENEMY] = enemyColumns;
|
||||
plugin.apList.tableColumns[plugin.apList.SIDE_FRIENDLY] = friendlyColumns;
|
||||
}
|
||||
|
||||
window.plugin.apList.setupCSS = function() {
|
||||
$("<style>")
|
||||
.prop("type", "text/css")
|
||||
.html("@@INCLUDESTRING:plugins/ap-list.css@@")
|
||||
.appendTo("head");
|
||||
}
|
||||
|
||||
window.plugin.apList.setupList = function() {
|
||||
var content = '<div id="ap-list">'
|
||||
+ '<span id="ap-list-side-labels">'
|
||||
+ '<span id="ap-list-eny">'
|
||||
+ '<a href="#" onclick="window.plugin.apList.displayEnemy();return false;">Enemy</a>'
|
||||
+ '</span>'
|
||||
+ '<span id="ap-list-frd">'
|
||||
+ '<a href="#" onclick="window.plugin.apList.displayFriendly();return false;">Friendly</a>'
|
||||
+ '</span>'
|
||||
+ '</span>'
|
||||
+ '<span id="ap-list-reload">'
|
||||
+ '<a href="#" title="Clear list and reload" onclick="window.plugin.apList.disableCache();'
|
||||
+ 'plugin.apList.hideReloadLabel();return false;">↻ R</a>'
|
||||
+ '</span>'
|
||||
+ '<div id="ap-list-table"></div>'
|
||||
+ '<span id="ap-list-misc-info" title="Stats">...</span>'
|
||||
+ '<span id="ap-list-pagination"></span>'
|
||||
+ '</div>';
|
||||
|
||||
$('#sidebar').append(content);
|
||||
$('#ap-list-reload').hide();
|
||||
}
|
||||
|
||||
window.plugin.apList.setupPagination = function() {
|
||||
var content = '<div class="ap-list-center-div">'
|
||||
+ '<div id="ap-list-first-p" class="ap-list-page-control" onclick="plugin.apList.changePage(-1, true);">'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-left ap-list-triangle-left-half"/>'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-left ap-list-triangle-left-half"/>'
|
||||
+ '</div>'
|
||||
+ '<div id="ap-list-next-p" class="ap-list-page-control" onclick="plugin.apList.changePage(-1);">'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-left ap-list-triangle-left-full"/>'
|
||||
+ '</div>'
|
||||
+ '<div id="ap-list-current-p" class="ap-list-page-text">1</div>'
|
||||
+ '<div id="ap-list-page-slash" class="ap-list-page-text">/</div>'
|
||||
+ '<div id="ap-list-total-p" class="ap-list-page-text">1</div>'
|
||||
+ '<div id="ap-list-prev-p" class="ap-list-page-control" onclick="plugin.apList.changePage(1);">'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-right ap-list-triangle-right-full"/>'
|
||||
+ '</div>'
|
||||
+ '<div id="ap-list-last-p" class="ap-list-page-control" onclick="plugin.apList.changePage(1, true);">'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-right ap-list-triangle-right-half"/>'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-right ap-list-triangle-right-half"/>'
|
||||
+ '</div>'
|
||||
+ '<div class="spacer" style="clear: both;"></div>'// fix collapsion of parent caused by inner div's float:left
|
||||
+ '</div>';
|
||||
$('#ap-list-pagination').html(content);
|
||||
}
|
||||
|
||||
window.plugin.apList.setupMapEvent = function() {
|
||||
map.on('zoomstart', function() {
|
||||
plugin.apList.setupMapEvent.zoomLevelBefore = map.getZoom();
|
||||
// Stop changing cacheBounds if cache enabled
|
||||
if(!plugin.apList.useCachedPortals)
|
||||
plugin.apList.cacheBounds = map.getBounds();
|
||||
});
|
||||
|
||||
map.on('zoomend', function() {
|
||||
// if zooming in and cache not yet enable, enable it
|
||||
if(!plugin.apList.useCachedPortals
|
||||
&& map.getZoom() > plugin.apList.setupMapEvent.zoomLevelBefore) {
|
||||
plugin.apList.enableCache();
|
||||
plugin.apList.showReloadLabel();
|
||||
}
|
||||
});
|
||||
|
||||
map.on('moveend zoomend', function() {
|
||||
// disable cache after out of cache bounds
|
||||
if(plugin.apList.useCachedPortals) {
|
||||
var currentBounds = map.getBounds();
|
||||
if(!plugin.apList.cacheBounds.contains(currentBounds)) {
|
||||
plugin.apList.disableCache();
|
||||
plugin.apList.hideReloadLabel();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.plugin.apList.setupVar();
|
||||
window.plugin.apList.setupSorting();
|
||||
window.plugin.apList.setupTableColumns();
|
||||
window.plugin.apList.setupCSS();
|
||||
window.plugin.apList.setupList();
|
||||
window.plugin.apList.setupPagination();
|
||||
window.plugin.apList.setupMapEvent();
|
||||
window.addHook('mapDataRefreshEnd', window.plugin.apList.handleUpdate);
|
||||
}
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-bookmarks@ZasoGD
|
||||
// @name IITC plugin: Bookmarks for maps and portals
|
||||
// @category Controls
|
||||
// @version 0.2.6.@@DATETIMEVERSION@@
|
||||
// @version 0.2.7.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -335,10 +335,11 @@
|
||||
// If portal isn't saved in bookmarks: Add this bookmark
|
||||
else{
|
||||
// Get portal name and coordinates
|
||||
var d = window.portals[guid].options.details;
|
||||
var label = d.portalV2.descriptiveText.TITLE;
|
||||
var lat = (d.locationE6.latE6)/1E6;
|
||||
var lng = (d.locationE6.lngE6)/1E6;
|
||||
var p = window.portals[guid];
|
||||
var d = p.options.data;
|
||||
var label = d.title;
|
||||
var lat = p.getLatLng().lat;
|
||||
var lng = p.getLatLng().lng;
|
||||
var latlng = lat+','+lng;
|
||||
|
||||
var ID = window.plugin.bookmarks.generateID();
|
||||
|
942
plugins/broken/ap-list.user.js
Normal file
942
plugins/broken/ap-list.user.js
Normal file
@ -0,0 +1,942 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-ap-list@xelio
|
||||
// @name IITC plugin: AP List
|
||||
// @category Info
|
||||
// @version 0.5.7.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] List portals by AP of either faction or by effective level. Other functions and controls please refer to the Userguide.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.apList = function() {
|
||||
};
|
||||
|
||||
window.plugin.apList.cachedPortals = {};
|
||||
window.plugin.apList.SIDE_FRIENDLY = 0;
|
||||
window.plugin.apList.SIDE_ENEMY = 1;
|
||||
window.plugin.apList.displaySide = window.plugin.apList.SIDE_ENEMY;
|
||||
window.plugin.apList.sides = new Array(2);
|
||||
window.plugin.apList.sortedPortals = new Array(2);
|
||||
window.plugin.apList.playerApGainFunc = new Array(2);
|
||||
|
||||
window.plugin.apList.SORT_BY_AP = 'AP';
|
||||
window.plugin.apList.SORT_BY_EL = 'EL';
|
||||
window.plugin.apList.sortBy = window.plugin.apList.SORT_BY_AP;
|
||||
window.plugin.apList.SORT_ASC = 1;
|
||||
window.plugin.apList.SORT_DESC = -1;
|
||||
window.plugin.apList.sortOptions = {};
|
||||
|
||||
window.plugin.apList.currentPage = [1,1];
|
||||
window.plugin.apList.totalPage = [1,1];
|
||||
window.plugin.apList.portalPerPage = 10;
|
||||
window.plugin.apList.sideLabelClass = {};
|
||||
window.plugin.apList.tableColumns = new Array(2);
|
||||
|
||||
window.plugin.apList.useCachedPortals = false;
|
||||
window.plugin.apList.cacheBounds;
|
||||
window.plugin.apList.cacheActiveZoomLevel;
|
||||
|
||||
window.plugin.apList.destroyPortalsGuid = new Array();
|
||||
|
||||
window.plugin.apList.portalLocationIndicator;
|
||||
window.plugin.apList.animTimeout;
|
||||
|
||||
// ENTRY POINT ///////////////////////////////////////////////////////////////////
|
||||
window.plugin.apList.handleUpdate = function() {
|
||||
if(!requests.isLastRequest('getThinnedEntitiesV4')) return;
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
// CONTENT GENERATION ////////////////////////////////////////////////////////////
|
||||
|
||||
// Generate html table from top portals
|
||||
window.plugin.apList.updatePortalTable = function(side) {
|
||||
var table = '<table id="ap-list-table">'
|
||||
+ '<thead>'
|
||||
+ plugin.apList.tableHeaderBuilder(side)
|
||||
+ '</thead>';
|
||||
|
||||
table += '<tbody>';
|
||||
var startingPortal = (plugin.apList.currentPage[side] - 1) * plugin.apList.portalPerPage;
|
||||
for(var i = startingPortal; i < startingPortal + plugin.apList.portalPerPage; i++) {
|
||||
var portal = plugin.apList.sortedPortals[side][i];
|
||||
table += plugin.apList.tableRowBuilder(side, portal);
|
||||
}
|
||||
table += '</tbody></table>';
|
||||
$('div#ap-list-table').html(table);
|
||||
|
||||
plugin.apList.updatePaginationControl();
|
||||
plugin.apList.updateStats();
|
||||
}
|
||||
|
||||
window.plugin.apList.tableHeaderBuilder = function(side) {
|
||||
var headerRow = '<tr>';
|
||||
|
||||
$.each(plugin.apList.tableColumns[side], function(ind, column) {
|
||||
var cssClass = column.headerTooltip ? (column.cssClass + ' help') : column.cssClass;
|
||||
var title = column.headerTooltip ? column.headerTooltip : '';
|
||||
var onclick = column.headerOnClick ? column.headerOnClick: '';
|
||||
var content = column.headerFunction ? column.headerFunction() : column.header;
|
||||
headerRow += '<td class="' + cssClass + '" '
|
||||
+ 'title="' + title + '" '
|
||||
+ 'onclick="' + onclick + '" '
|
||||
+ '>'
|
||||
+ content
|
||||
+ '</td>';
|
||||
});
|
||||
|
||||
headerRow += '</tr>';
|
||||
return headerRow;
|
||||
}
|
||||
|
||||
window.plugin.apList.tableRowBuilder = function(side,portal) {
|
||||
var row = "<tr>";
|
||||
|
||||
$.each(plugin.apList.tableColumns[side], function(ind, column) {
|
||||
var content = portal ? column.contentFunction(portal) : ' ';
|
||||
row += '<td class="' + column.cssClass + '">'
|
||||
+ content
|
||||
+ '</td>';
|
||||
});
|
||||
|
||||
row += '</tr>';
|
||||
return row;
|
||||
}
|
||||
|
||||
window.plugin.apList.getHeaderCheckbox = function() {
|
||||
var onClick = 'window.plugin.apList.clearDestroyPortals();';
|
||||
var content = '<div class="ap-list-checkbox-header" />'
|
||||
var div = plugin.apList.getCheckbox(onClick, null, content);
|
||||
return div;
|
||||
}
|
||||
|
||||
window.plugin.apList.getPortalDestroyCheckbox = function(portal) {
|
||||
// Change background color to border color if portal selected for destroy
|
||||
var addedClass = plugin.apList.destroyPortalIndex(portal.guid) >= 0
|
||||
? 'ap-list-checkbox-selected' : '';
|
||||
var onClick = 'window.plugin.apList.destroyPortal(\'' + portal.guid + '\');';
|
||||
var div = plugin.apList.getCheckbox(onClick, addedClass, null);
|
||||
return div;
|
||||
}
|
||||
|
||||
window.plugin.apList.getCheckbox = function(onClick, addedClass, content) {
|
||||
// 2 div for centering checkbox horizontally and vertically,
|
||||
// click event on outest div for people with not so good aiming
|
||||
var div = '<div class="ap-list-checkbox-outer" onclick="' + (onClick || '')+ '">'
|
||||
+ '<div class="ap-list-checkbox-inner ' + (addedClass || '') + '">'
|
||||
+ (content || '')
|
||||
+ '</div>'
|
||||
+ '</div>';
|
||||
return div;
|
||||
}
|
||||
|
||||
// Combine ap title and test
|
||||
window.plugin.apList.getPortalApText = function(portal) {
|
||||
var title = plugin.apList.getPortalApTitle(portal);
|
||||
return '<div class="help" title="' + title + '">' + digits(portal.playerApGain.totalAp) + '</div>';
|
||||
}
|
||||
|
||||
// Friendly portal will get resonator upgrade list, enemy
|
||||
// portal will get ap breakdown
|
||||
window.plugin.apList.getPortalApTitle = function(portal) {
|
||||
var t;
|
||||
var playerApGain = portal.playerApGain;
|
||||
if(plugin.apList.portalSide(portal) === plugin.apList.SIDE_FRIENDLY) {
|
||||
t = 'Deploy & Upgrade\n';
|
||||
|
||||
for(var i = 0; i < playerApGain.upgradedReso.length; i++) {
|
||||
var reso = playerApGain.upgradedReso[i];
|
||||
var apGain = (reso.level === 0) ? DEPLOY_RESONATOR : UPGRADE_ANOTHERS_RESONATOR;
|
||||
t += 'Resonator on ' + OCTANTS[reso.slot] + '\t' + reso.level + '->'
|
||||
+ reso.newLevel + '\t= ' + apGain + '\n';
|
||||
}
|
||||
|
||||
if(playerApGain.captureBonus > 0)
|
||||
t += 'Capture\t\t= ' + playerApGain.captureBonus + '\n';
|
||||
if(playerApGain.completionBonus > 0)
|
||||
t += 'Bonus\t\t= ' + playerApGain.completionBonus + '\n';
|
||||
|
||||
t += 'Sum: ' + digits(playerApGain.totalAp) + ' AP';
|
||||
} else {
|
||||
t = 'Destroy & Capture:\n'
|
||||
+ 'R:' + playerApGain.resoCount + ' L:' + playerApGain.linkCount + ' CF:' + playerApGain.fieldCount + '\n'
|
||||
+ 'Destroy AP\t=\t' + digits(playerApGain.destroyAp) + '\n'
|
||||
+ 'Capture AP\t=\t' + digits(playerApGain.captureAp) + '\n'
|
||||
+ 'Sum: ' + digits(playerApGain.totalAp) + ' AP';
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
window.plugin.apList.getPortalEffectiveLvText = function(portal) {
|
||||
var title = plugin.apList.getPortalEffectiveLvTitle(portal);
|
||||
return '<div class="help" title="' + title + '">' + portal.effectiveLevel.effectiveLevel.toFixed(1) + '</div>';
|
||||
}
|
||||
|
||||
window.plugin.apList.getPortalEffectiveLvTitle = function(portal) {
|
||||
var t = 'Effective energy:\t' + portal.effectiveLevel.effectiveEnergy + '\n'
|
||||
+ 'Effect of Shields:\t' + portal.effectiveLevel.effectOfShields + '\n'
|
||||
+ 'Effect of resos dist:\t' + portal.effectiveLevel.effectOfResoDistance + '\n'
|
||||
+ 'Origin Level:\t' + portal.effectiveLevel.originLevel;
|
||||
return t;
|
||||
}
|
||||
|
||||
// portal link - single click: select portal
|
||||
// double click: zoom to and select portal
|
||||
// hover: show address
|
||||
window.plugin.apList.getPortalLink = function(portal) {
|
||||
var latlng = [portal.locationE6.latE6/1E6, portal.locationE6.lngE6/1E6].join();
|
||||
var jsSingleClick = 'window.plugin.apList.selectPortal(\''+portal.guid+'\');return false';
|
||||
var jsDoubleClick = 'window.zoomToAndShowPortal(\''+portal.guid+'\', ['+latlng+']);return false';
|
||||
var perma = '/intel?latE6='+portal.locationE6.latE6
|
||||
+'&lngE6='+portal.locationE6.lngE6+'&z=17&pguid='+portal.guid;
|
||||
//Use Jquery to create the link, which escape characters in TITLE and ADDRESS of portal
|
||||
var a = $('<a>',{
|
||||
"class": 'help',
|
||||
text: portal.portalV2.descriptiveText.TITLE,
|
||||
title: portal.portalV2.descriptiveText.ADDRESS,
|
||||
href: perma,
|
||||
onClick: jsSingleClick,
|
||||
onDblClick: jsDoubleClick
|
||||
})[0].outerHTML;
|
||||
|
||||
var divClass = plugin.apList.destroyPortalIndex(portal.guid) >= 0
|
||||
? 'ap-list-link ap-list-link-selected'
|
||||
: 'ap-list-link';
|
||||
var div = '<div class="' + divClass + '">'+a+'</div>';
|
||||
return div;
|
||||
}
|
||||
|
||||
window.plugin.apList.updatePaginationControl = function() {
|
||||
$('#ap-list-current-p').html(plugin.apList.currentPage[plugin.apList.displaySide]);
|
||||
$('#ap-list-total-p').html(plugin.apList.totalPage[plugin.apList.displaySide]);
|
||||
}
|
||||
|
||||
window.plugin.apList.updateStats = function() {
|
||||
var destroyPortals = plugin.apList.destroyPortalsGuid.length;
|
||||
if(destroyPortals === 0) {
|
||||
title = 'Stats';
|
||||
} else {
|
||||
var destroyAP = 0;
|
||||
var averageEL = 0;
|
||||
$.each(plugin.apList.destroyPortalsGuid, function(ind,guid) {
|
||||
destroyAP += plugin.apList.cachedPortals[guid].playerApGain.totalAp;
|
||||
averageEL += plugin.apList.cachedPortals[guid].effectiveLevel.effectiveLevel;
|
||||
});
|
||||
averageEL = Math.round(averageEL / destroyPortals * 10) / 10;
|
||||
|
||||
var title = 'Stats\n'
|
||||
+ 'Selected portal(s)\t=\t' + destroyPortals + '\n'
|
||||
+ 'Total AP\t=\t' + destroyAP + '\n'
|
||||
+ 'Average EL\t=\t' + averageEL;
|
||||
}
|
||||
|
||||
$('#ap-list-misc-info').attr('title', title);
|
||||
}
|
||||
|
||||
// MAIN LOGIC FUNCTIONS //////////////////////////////////////////////////////////
|
||||
|
||||
// Loop through portals and get playerApGain, then put in sortedPortals by side and sort them by AP.
|
||||
window.plugin.apList.updateSortedPortals = function() {
|
||||
plugin.apList.sortedPortals[plugin.apList.SIDE_FRIENDLY] = new Array();
|
||||
plugin.apList.sortedPortals[plugin.apList.SIDE_ENEMY] = new Array();
|
||||
|
||||
// Make a backup of cachedPortals with shallow copy
|
||||
// If cache is not enabled, empty cachedPortals. In following
|
||||
// "$.each" loop, the backup portal will copy back into
|
||||
// cachedPortals if it exist in "window.portals"" and didn't change.'
|
||||
var oldcachedPortal = $.extend({},plugin.apList.cachedPortals);
|
||||
if(!plugin.apList.useCachedPortals)
|
||||
plugin.apList.cachedPortals = {};
|
||||
|
||||
$.each(window.portals, function(key, value) {
|
||||
var portal = value.options.details;
|
||||
var cachedPortal = oldcachedPortal[key];
|
||||
// If portal is changed, update playerApGain with latest
|
||||
// information
|
||||
if(!cachedPortal
|
||||
|| value.timestamp !== cachedPortal.timestamp
|
||||
|| plugin.apList.isFieldsChanged(portal.portalV2.linkedFields, cachedPortal.portalV2.linkedFields)) {
|
||||
// Shallow copy portal detail to cachedPortal
|
||||
cachedPortal = $.extend({}, portal);
|
||||
var side = plugin.apList.portalSide(portal);
|
||||
var getApGainFunc = plugin.apList.playerApGainFunc[side];
|
||||
// Assign playerApGain and guid to cachedPortal
|
||||
cachedPortal.timestamp = value.timestamp
|
||||
cachedPortal.playerApGain = getApGainFunc(portal);
|
||||
cachedPortal.effectiveLevel = plugin.apList.getEffectiveLevel(portal);
|
||||
cachedPortal.guid = value.options.guid;
|
||||
}
|
||||
plugin.apList.cachedPortals[key] = cachedPortal;
|
||||
});
|
||||
|
||||
// Add all portals to sortedPortals by side and sort sortedPortals by AP
|
||||
$.each(plugin.apList.cachedPortals, function(key, portal) {
|
||||
var side = plugin.apList.portalSide(portal);
|
||||
plugin.apList.sortedPortals[side].push(portal);
|
||||
});
|
||||
$.each(plugin.apList.sides, function(ind, side) {
|
||||
plugin.apList.sortedPortals[side].sort(plugin.apList.comparePortal);
|
||||
});
|
||||
|
||||
// Modify sortedPortals if any portal selected for destroy
|
||||
plugin.apList.handleDestroyPortal();
|
||||
// Update pagination control data
|
||||
plugin.apList.updateTotalPages();
|
||||
}
|
||||
|
||||
// This function will make AP gain of field and link only count once if
|
||||
// one of the connected portal is selected for destroy
|
||||
window.plugin.apList.handleDestroyPortal = function() {
|
||||
if(plugin.apList.destroyPortalsGuid.length === 0) return;
|
||||
|
||||
var enemy = window.plugin.apList.SIDE_ENEMY;
|
||||
var destroyedLinks = {};
|
||||
var destroyedFields = {};
|
||||
|
||||
// Clean up portal selected for destroy, remove from destroyPortalsGuid
|
||||
// if portal not exist or change to friendly side
|
||||
plugin.apList.destroyPortalsGuid = $.grep(plugin.apList.destroyPortalsGuid, function(portalGuid,ind) {
|
||||
var portal = plugin.apList.cachedPortals[portalGuid];
|
||||
if(!portal || plugin.apList.portalSide(portal) !== enemy) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Loop through portals from highest AP to lowest AP, matching links and fields to the
|
||||
// portal only if the portal is selected for destroy and have highest AP.
|
||||
// Matching info stores in "destroyedLinks" and "destroyedFields"
|
||||
$.each(plugin.apList.sortedPortals[enemy], function(ind, portal) {
|
||||
if(plugin.apList.destroyPortalIndex(portal.guid) < 0) return true;
|
||||
|
||||
$.each(portal.portalV2.linkedEdges || [], function(ind,link) {
|
||||
// Skip if the link already matched with a portal
|
||||
if(destroyedLinks[link.edgeGuid]) return true;
|
||||
belongTo = {portalGuid: portal.guid};
|
||||
destroyedLinks[link.edgeGuid] = belongTo;
|
||||
});
|
||||
$.each(portal.portalV2.linkedFields || [], function(ind,field) {
|
||||
// Skip if the field already matched with a portal
|
||||
if(destroyedFields[field]) return true;
|
||||
belongTo = {portalGuid: portal.guid};
|
||||
destroyedFields[field] = belongTo;
|
||||
});
|
||||
});
|
||||
|
||||
// Remove the link and field which was matched with another portal
|
||||
var getApGainFunc = plugin.apList.playerApGainFunc[enemy];
|
||||
$.each(plugin.apList.sortedPortals[enemy], function(ind, portal) {
|
||||
// Filter out links which was matched with another portal
|
||||
var newLinkedEdges = $.grep(portal.portalV2.linkedEdges || [], function(link,ind) {
|
||||
if(!destroyedLinks[link.edgeGuid]) return true;
|
||||
return (destroyedLinks[link.edgeGuid].portalGuid === portal.guid);
|
||||
});
|
||||
// Filter out fields which was matched with another portal
|
||||
var newLinkedFields = $.grep(portal.portalV2.linkedFields || [], function(field,ind) {
|
||||
if(!destroyedFields[field]) return true;
|
||||
return (destroyedFields[field].portalGuid === portal.guid);
|
||||
});
|
||||
|
||||
// Skip modifying portal if no link and field changed
|
||||
if(newLinkedEdges.length === (portal.portalV2.linkedEdges || []).length
|
||||
&& newLinkedFields.length === (portal.portalV2.linkedFields || []).length)
|
||||
return true;
|
||||
|
||||
// Clone the portal with deep copy to avoid modifying original data in cachedPortal
|
||||
var newPortal = $.extend(true, {}, portal);
|
||||
// Assign new links and fields and calculate new playerApGain
|
||||
if(portal.portalV2.linkedEdges) newPortal.portalV2.linkedEdges = newLinkedEdges;
|
||||
if(portal.portalV2.linkedFields) newPortal.portalV2.linkedFields = newLinkedFields;
|
||||
newPortal.playerApGain = getApGainFunc(newPortal);
|
||||
|
||||
plugin.apList.sortedPortals[enemy][ind] = newPortal;
|
||||
});
|
||||
|
||||
// Sorting portals with updated AP
|
||||
plugin.apList.sortedPortals[enemy].sort(plugin.apList.comparePortal);
|
||||
}
|
||||
|
||||
window.plugin.apList.updateTotalPages = function() {
|
||||
$.each(plugin.apList.sortedPortals, function(side, portals) {
|
||||
plugin.apList.totalPage[side] = Math.max(Math.ceil(portals.length / plugin.apList.portalPerPage), 1);
|
||||
plugin.apList.currentPage[side] = Math.min(plugin.apList.totalPage[side], plugin.apList.currentPage[side]);
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.apList.isFieldsChanged = function(a,b) {
|
||||
// http://stackoverflow.com/questions/1773069/using-jquery-to-compare-two-arrays
|
||||
return $(a).not(b).get().length === 0 && $(b).not(a).get().length === 0;;
|
||||
}
|
||||
|
||||
window.plugin.apList.portalSide = function(portal) {
|
||||
return (portal.controllingTeam.team === PLAYER.team
|
||||
|| portal.controllingTeam.team === 'NEUTRAL')
|
||||
? plugin.apList.SIDE_FRIENDLY
|
||||
: plugin.apList.SIDE_ENEMY;
|
||||
}
|
||||
|
||||
// Get AP of friendly portal
|
||||
window.plugin.apList.getDeployOrUpgradeApGain = function(d) {
|
||||
var playerResoCount = new Array(MAX_PORTAL_LEVEL + 1);
|
||||
var otherReso = new Array();
|
||||
var totalAp = 0;
|
||||
var upgradedReso = new Array();
|
||||
|
||||
var deployCount = 0;
|
||||
var upgradedCount = 0;
|
||||
|
||||
var captureBonus = 0;
|
||||
var completionBonus = 0;
|
||||
|
||||
// loop through reso slot and find empty reso, deployed
|
||||
// by others(only level lower than player level) or by player.
|
||||
for(var i = 0; i < 8; i++) {
|
||||
var reso = d.resonatorArray.resonators[i];
|
||||
// Empty reso
|
||||
if(!reso) {
|
||||
otherReso.push({slot: i, level: 0});
|
||||
continue;
|
||||
}
|
||||
// By player
|
||||
if(reso.ownerGuid === window.PLAYER.guid) {
|
||||
playerResoCount[reso.level] = (playerResoCount[reso.level] || 0) + 1;
|
||||
continue;
|
||||
}
|
||||
// By others and level lower than player
|
||||
if(reso.level < window.PLAYER.level) {
|
||||
otherReso.push(reso);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort others reso low to high, last reso in otherReso get upgrade first.
|
||||
otherReso.sort(function(a, b) {return a.level - b.level;});
|
||||
|
||||
// Find out available count of reso for each level
|
||||
for(var i = window.PLAYER.level; i > 0 && otherReso.length > 0; i--) {
|
||||
var availableCount = MAX_RESO_PER_PLAYER[i] - (playerResoCount[i] || 0);
|
||||
// Loop through lower level reso of others and add to result
|
||||
while(availableCount > 0 && otherReso.length > 0) {
|
||||
var targetReso = otherReso.pop();
|
||||
// Can only upgrade lower level reso
|
||||
if(targetReso.level >= i)
|
||||
continue;
|
||||
// Add upgraded reso to result
|
||||
targetReso.newLevel = i;
|
||||
upgradedReso.push(targetReso);
|
||||
// Counting upgrade or deploy
|
||||
(targetReso.level === 0) ? deployCount++ : upgradedCount++;
|
||||
|
||||
availableCount--;
|
||||
}
|
||||
}
|
||||
|
||||
if(deployCount > 0) completionBonus = COMPLETION_BONUS;
|
||||
if(deployCount === 8) captureBonus = CAPTURE_PORTAL;
|
||||
|
||||
totalAp = deployCount * DEPLOY_RESONATOR
|
||||
+ upgradedCount * UPGRADE_ANOTHERS_RESONATOR
|
||||
+ captureBonus
|
||||
+ completionBonus;
|
||||
|
||||
return {
|
||||
captureBonus: captureBonus,
|
||||
completionBonus: completionBonus,
|
||||
totalAp: totalAp,
|
||||
upgradedReso: upgradedReso
|
||||
};
|
||||
}
|
||||
|
||||
window.plugin.apList.getAttackApGain = function(d) {
|
||||
var resoCount = 0;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if (!reso)
|
||||
return true;
|
||||
resoCount += 1;
|
||||
});
|
||||
|
||||
var linkCount = d.portalV2.linkedEdges ? d.portalV2.linkedEdges.length : 0;
|
||||
var fieldCount = d.portalV2.linkedFields ? d.portalV2.linkedFields.length : 0;
|
||||
|
||||
var resoAp = resoCount * DESTROY_RESONATOR;
|
||||
var linkAp = linkCount * DESTROY_LINK;
|
||||
var fieldAp = fieldCount * DESTROY_FIELD;
|
||||
var destroyAp = resoAp + linkAp + fieldAp;
|
||||
var captureAp = CAPTURE_PORTAL + 8 * DEPLOY_RESONATOR + COMPLETION_BONUS;
|
||||
var totalAp = destroyAp + captureAp;
|
||||
|
||||
return {
|
||||
totalAp: totalAp,
|
||||
destroyAp: destroyAp,
|
||||
captureAp: captureAp,
|
||||
resoCount: resoCount,
|
||||
linkCount: linkCount,
|
||||
fieldCount: fieldCount
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.apList.getEffectiveLevel = function(portal) {
|
||||
var effectiveEnergy = 0;
|
||||
var effectiveLevel = 0;
|
||||
|
||||
var resosStats = plugin.apList.getResonatorsStats(portal);
|
||||
|
||||
|
||||
// Calculate effective energy
|
||||
|
||||
var effectOfShields = plugin.apList.getShieldsEffect(portal);
|
||||
|
||||
// If avgResoDistance is 0, 8 resonators in the same place and can be treated as 1 resonator.
|
||||
// So the minimum effect of resonator distance is 1/8
|
||||
var effectOfResoDistance = (1 + (resosStats.avgResoDistance / HACK_RANGE) * 7 ) / 8;
|
||||
|
||||
effectiveEnergy = resosStats.currentEnergy * effectOfShields * effectOfResoDistance;
|
||||
|
||||
// Calculate effective level
|
||||
for(var i = MAX_PORTAL_LEVEL; i >= 0; i--) {
|
||||
var baseLevel = i;
|
||||
var baseLevelEnergy = RESO_NRG[baseLevel] * 8;
|
||||
if(effectiveEnergy >= baseLevelEnergy) {
|
||||
var energyToNextLevel = baseLevel === MAX_PORTAL_LEVEL
|
||||
? baseLevelEnergy - RESO_NRG[MAX_PORTAL_LEVEL - 1] * 8 // Extrapolate
|
||||
: RESO_NRG[baseLevel + 1] * 8 - baseLevelEnergy; // Interpolate
|
||||
|
||||
var additionalLevel = (effectiveEnergy - baseLevelEnergy) / energyToNextLevel;
|
||||
effectiveLevel = baseLevel + additionalLevel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Account for damage do to player by portal
|
||||
var portalLevel = parseInt(getPortalLevel(portal));
|
||||
if(effectiveLevel < portalLevel) {
|
||||
var energyPect = resosStats.currentEnergy / resosStats.totalEnergy;
|
||||
effectiveLevel = effectiveLevel * (1-energyPect) + portalLevel * energyPect;
|
||||
}
|
||||
|
||||
return {
|
||||
effectiveLevel: Math.round(effectiveLevel * 10) / 10,
|
||||
effectiveEnergy: parseInt(effectiveEnergy),
|
||||
effectOfShields: Math.round(effectOfShields * 100) / 100,
|
||||
effectOfResoDistance: Math.round(effectOfResoDistance * 100) / 100,
|
||||
originLevel: portalLevel
|
||||
};
|
||||
}
|
||||
|
||||
window.plugin.apList.getResonatorsStats = function(portal) {
|
||||
var totalEnergy = 0;
|
||||
var currentEnergy = 0;
|
||||
var avgResoDistance = 0;
|
||||
|
||||
$.each(portal.resonatorArray.resonators, function(ind, reso) {
|
||||
if (!reso)
|
||||
return true;
|
||||
totalEnergy += RESO_NRG[reso.level];
|
||||
currentEnergy += reso.energyTotal;
|
||||
avgResoDistance += (reso.distanceToPortal / 8);
|
||||
});
|
||||
return {
|
||||
totalEnergy: totalEnergy,
|
||||
currentEnergy: currentEnergy,
|
||||
avgResoDistance: avgResoDistance};
|
||||
}
|
||||
|
||||
window.plugin.apList.getShieldsEffect = function(portal) {
|
||||
// shield effect: each shield's mitigation value is assumed to be the percentage of the damage it will absorb
|
||||
// the rest of the damage gets through to the next shield, and so on.
|
||||
// so, to calculate the total protection, we multiply the fractions of damage allowed through each shield
|
||||
// to get a final figure of how much damage gets through
|
||||
// e.g.
|
||||
// one shield: mitigation 10 - lets 90% of the damage through
|
||||
// two shields: mitigation 20 and 30 - first one lets 80% through, second 70% of the remaining
|
||||
// so final amount let through = 0.8 * 0.7 = 0.56 = 56% damage let through
|
||||
// four shields: mitigation 30 - 70% through each = 0.7 * 0.7 * 0.7 * 0.7 = 0.24 = 24% damage gets through all four
|
||||
|
||||
var shieldsEffect = 1;
|
||||
$.each(portal.portalV2.linkedModArray, function(ind, mod) {
|
||||
if(!mod)
|
||||
return true;
|
||||
if(!mod.stats.MITIGATION)
|
||||
return true;
|
||||
shieldsEffect *= (1 - parseInt(mod.stats.MITIGATION)/100.0);
|
||||
});
|
||||
return shieldsEffect;
|
||||
}
|
||||
|
||||
// For using in .sort(func) of sortedPortals
|
||||
// Use options in plugin.apList.sortOptions. Each type of sortBy has
|
||||
// array of options. Option consist of an ordering and a property chain.
|
||||
//
|
||||
// Sorting done by loop through the options, get the property by
|
||||
// property chain of each option, compare the property of two object
|
||||
// with the ordering of option and return the result when the first
|
||||
// difference is found.
|
||||
window.plugin.apList.comparePortal = function(a,b) {
|
||||
var result = 0;
|
||||
var options = plugin.apList.sortOptions[plugin.apList.sortBy];
|
||||
|
||||
$.each(options, function(indO, option) {
|
||||
var aProperty = a;
|
||||
var bProperty = b;
|
||||
// Walking down the chain
|
||||
$.each(option.chain, function(indPN, propertyName) {
|
||||
aProperty = aProperty[propertyName];
|
||||
bProperty = bProperty[propertyName];
|
||||
});
|
||||
// compare next property if equal
|
||||
if(aProperty === bProperty) return true;
|
||||
|
||||
result = (aProperty > bProperty ? 1 : -1) * option.order;
|
||||
return false;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FEATURE TOGGLES AND INTERACTION HANDLER ///////////////////////////////////////
|
||||
|
||||
window.plugin.apList.enableCache = function() {
|
||||
plugin.apList.useCachedPortals = true;
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
window.plugin.apList.disableCache = function() {
|
||||
plugin.apList.useCachedPortals = false;
|
||||
plugin.apList.cachedPortals = {};
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
window.plugin.apList.selectPortal = function(guid) {
|
||||
// Add error catching to avoid following link of portal if error
|
||||
// occurred in renderPortalDetails or hooked plugin
|
||||
try {
|
||||
renderPortalDetails(guid);
|
||||
} catch(e) {
|
||||
console.error(e.message);
|
||||
console.log(e.stack);
|
||||
console.log('Skipping error in renderPortalDetails or hooked plugin')
|
||||
}
|
||||
plugin.apList.setPortalLocationIndicator(guid);
|
||||
}
|
||||
|
||||
window.plugin.apList.setPortalLocationIndicator = function(guid) {
|
||||
var portal = window.portals[guid];
|
||||
if(!portal) return;
|
||||
var startRadius = screen.availWidth / 2;
|
||||
var portalRadius = portal.options.radius;
|
||||
var latlng = portal.getLatLng();
|
||||
var property = {
|
||||
radius: startRadius,
|
||||
fill: false,
|
||||
color: COLOR_SELECTED_PORTAL,
|
||||
weight: 2,
|
||||
opacity: 1,
|
||||
portalRadius: portalRadius,
|
||||
clickable: false };
|
||||
|
||||
if(plugin.apList.portalLocationIndicator)
|
||||
map.removeLayer(plugin.apList.portalLocationIndicator);
|
||||
if(plugin.apList.animTimeout)
|
||||
clearTimeout(plugin.apList.animTimeout);
|
||||
plugin.apList.portalLocationIndicator = L.circleMarker(latlng, property).addTo(map);
|
||||
plugin.apList.animTimeout = setTimeout(plugin.apList.animPortalLocationIndicator,100);
|
||||
}
|
||||
|
||||
window.plugin.apList.animPortalLocationIndicator = function() {
|
||||
var radius = plugin.apList.portalLocationIndicator.options.radius;
|
||||
var portalRadius = plugin.apList.portalLocationIndicator.options.portalRadius
|
||||
if(radius > portalRadius) {
|
||||
var step = radius / 3;
|
||||
if(radius < 80) step = step / 3;
|
||||
var newRadius = plugin.apList.portalLocationIndicator.options.radius -= step;
|
||||
plugin.apList.portalLocationIndicator.setRadius(newRadius);
|
||||
if(plugin.apList.animTimeout)
|
||||
clearTimeout(plugin.apList.animTimeout);
|
||||
plugin.apList.animTimeout = setTimeout(plugin.apList.animPortalLocationIndicator,100);
|
||||
} else {
|
||||
map.removeLayer(plugin.apList.portalLocationIndicator);
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.apList.changePage = function(step, toEnd) {
|
||||
var side = plugin.apList.displaySide;
|
||||
var oldPage = plugin.apList.currentPage[side];
|
||||
|
||||
if(toEnd) {
|
||||
if(step < 0) plugin.apList.currentPage[side] = 1;
|
||||
if(step > 0) plugin.apList.currentPage[side] = plugin.apList.totalPage[side]
|
||||
} else {
|
||||
plugin.apList.currentPage[side] += step;
|
||||
if(plugin.apList.currentPage[side] < 1)
|
||||
plugin.apList.currentPage[side] = 1;
|
||||
if(plugin.apList.currentPage[side] > plugin.apList.totalPage[side])
|
||||
plugin.apList.currentPage[side] = plugin.apList.totalPage[side];
|
||||
}
|
||||
|
||||
if(plugin.apList.currentPage[side] !== oldPage)
|
||||
plugin.apList.updatePortalTable(side);
|
||||
}
|
||||
|
||||
window.plugin.apList.changeSorting = function(sortBy) {
|
||||
var oldSortBy = plugin.apList.sortBy;
|
||||
plugin.apList.sortBy = sortBy;
|
||||
if(plugin.apList.sortBy !== oldSortBy) {
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.apList.clearDestroyPortals = function() {
|
||||
plugin.apList.destroyPortalsGuid = new Array();
|
||||
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
window.plugin.apList.destroyPortal = function(guid) {
|
||||
// Add to destroyPortalsGuid if not yet added, remove if already added
|
||||
var portalIndex = plugin.apList.destroyPortalIndex(guid);
|
||||
if(portalIndex >= 0) {
|
||||
plugin.apList.destroyPortalsGuid.splice(portalIndex, 1);
|
||||
} else {
|
||||
plugin.apList.destroyPortalsGuid.push(guid);
|
||||
}
|
||||
|
||||
plugin.apList.updateSortedPortals();
|
||||
plugin.apList.updatePortalTable(plugin.apList.displaySide);
|
||||
}
|
||||
|
||||
// Return the index of portal in destroyPortalsGuid
|
||||
window.plugin.apList.destroyPortalIndex = function(guid) {
|
||||
return $.inArray(guid, plugin.apList.destroyPortalsGuid);
|
||||
}
|
||||
|
||||
// Change display table to friendly portals
|
||||
window.plugin.apList.displayFriendly = function() {
|
||||
plugin.apList.changeDisplaySide(plugin.apList.SIDE_FRIENDLY);
|
||||
}
|
||||
|
||||
// Change display table to enemy portals
|
||||
window.plugin.apList.displayEnemy = function() {
|
||||
plugin.apList.changeDisplaySide(plugin.apList.SIDE_ENEMY);
|
||||
}
|
||||
|
||||
window.plugin.apList.changeDisplaySide = function(side) {
|
||||
var isChange = (plugin.apList.displaySide !== side);
|
||||
var scrollTo = 0;
|
||||
if(isChange) {
|
||||
plugin.apList.displaySide = side;
|
||||
plugin.apList.updatePortalTable(side);
|
||||
plugin.apList.toggleSideLabel(side);
|
||||
scrollTo = $("#ap-list").position().top + $("#ap-list").outerHeight()
|
||||
- $("#sidebar").height() + $("#sidebar").scrollTop();
|
||||
}
|
||||
$('#sidebar').scrollTop(scrollTo);
|
||||
}
|
||||
|
||||
window.plugin.apList.toggleSideLabel = function(side) {
|
||||
$.each(plugin.apList.sides, function(ind,key) {
|
||||
var labelClass = plugin.apList.sideLabelClass[key];
|
||||
var opacity = (key === side) ? 1.0 : 0.5;
|
||||
$(labelClass).css("opacity", opacity);
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.apList.hideReloadLabel = function() {
|
||||
$('#ap-list-reload').hide();
|
||||
}
|
||||
|
||||
window.plugin.apList.showReloadLabel = function() {
|
||||
$('#ap-list-reload').show();
|
||||
}
|
||||
|
||||
// SETUP /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
window.plugin.apList.setupVar = function() {
|
||||
plugin.apList.sides[plugin.apList.SIDE_FRIENDLY] = plugin.apList.SIDE_FRIENDLY;
|
||||
plugin.apList.sides[plugin.apList.SIDE_ENEMY] = plugin.apList.SIDE_ENEMY;
|
||||
plugin.apList.playerApGainFunc[plugin.apList.SIDE_FRIENDLY]
|
||||
= plugin.apList.getDeployOrUpgradeApGain;
|
||||
plugin.apList.playerApGainFunc[plugin.apList.SIDE_ENEMY]
|
||||
= plugin.apList.getAttackApGain;
|
||||
plugin.apList.sideLabelClass[plugin.apList.SIDE_FRIENDLY]
|
||||
= "#ap-list-frd";
|
||||
plugin.apList.sideLabelClass[plugin.apList.SIDE_ENEMY]
|
||||
= "#ap-list-eny";
|
||||
plugin.apList.sortedPortals[plugin.apList.SIDE_FRIENDLY] = new Array();
|
||||
plugin.apList.sortedPortals[plugin.apList.SIDE_ENEMY] = new Array();
|
||||
}
|
||||
|
||||
window.plugin.apList.setupSorting = function() {
|
||||
var optionELAsc = {
|
||||
order: plugin.apList.SORT_ASC,
|
||||
chain: ['effectiveLevel','effectiveLevel']};
|
||||
var optionAPDesc = {
|
||||
order: plugin.apList.SORT_DESC,
|
||||
chain: ['playerApGain','totalAp']};
|
||||
var optionGuidDesc = {
|
||||
order: plugin.apList.SORT_DESC,
|
||||
chain: ['guid']};
|
||||
|
||||
// order by EL -> AP -> guid
|
||||
plugin.apList.sortOptions[plugin.apList.SORT_BY_EL] = [optionELAsc, optionAPDesc, optionGuidDesc];
|
||||
// order by AP -> EL -> guid
|
||||
plugin.apList.sortOptions[plugin.apList.SORT_BY_AP] = [optionAPDesc, optionELAsc, optionGuidDesc];
|
||||
}
|
||||
|
||||
// Setup table columns for header builder and row builder
|
||||
window.plugin.apList.setupTableColumns = function() {
|
||||
var enemyColumns = new Array();
|
||||
var friendlyColumns = new Array();
|
||||
|
||||
// AP and Eff. LV columns are same in enemy and friendly table
|
||||
var apColumn = {
|
||||
header: 'AP',
|
||||
headerOnClick: 'plugin.apList.changeSorting(plugin.apList.SORT_BY_AP);',
|
||||
headerTooltip: 'Click to sort by AP',
|
||||
cssClass: 'ap-list-td-ap',
|
||||
contentFunction: plugin.apList.getPortalApText
|
||||
};
|
||||
var effectiveLevelColumn = {
|
||||
header: 'EL',
|
||||
headerOnClick: 'plugin.apList.changeSorting(plugin.apList.SORT_BY_EL);',
|
||||
headerTooltip: 'Effective Level\nClick to sort by EL',
|
||||
cssClass: 'ap-list-td-eff-lv',
|
||||
contentFunction: plugin.apList.getPortalEffectiveLvText
|
||||
};
|
||||
|
||||
// Columns: Checkbox | Portal | AP | Eff. LV
|
||||
enemyColumns.push({
|
||||
headerFunction: plugin.apList.getHeaderCheckbox,
|
||||
headerTooltip: 'Unselect all',
|
||||
cssClass: 'ap-list-td-checkbox',
|
||||
contentFunction: plugin.apList.getPortalDestroyCheckbox
|
||||
});
|
||||
enemyColumns.push({
|
||||
header: 'Portal',
|
||||
cssClass: 'ap-list-td-link ap-list-td-link-eny',
|
||||
contentFunction: plugin.apList.getPortalLink
|
||||
});
|
||||
enemyColumns.push(apColumn);
|
||||
enemyColumns.push(effectiveLevelColumn);
|
||||
|
||||
// Columns: Portal | AP | Eff. LV
|
||||
friendlyColumns.push({
|
||||
header: 'Portal',
|
||||
cssClass: 'ap-list-td-link ap-list-td-link-frd',
|
||||
contentFunction: plugin.apList.getPortalLink
|
||||
});
|
||||
friendlyColumns.push(apColumn);
|
||||
friendlyColumns.push(effectiveLevelColumn);
|
||||
|
||||
plugin.apList.tableColumns[plugin.apList.SIDE_ENEMY] = enemyColumns;
|
||||
plugin.apList.tableColumns[plugin.apList.SIDE_FRIENDLY] = friendlyColumns;
|
||||
}
|
||||
|
||||
window.plugin.apList.setupCSS = function() {
|
||||
$("<style>")
|
||||
.prop("type", "text/css")
|
||||
.html("@@INCLUDESTRING:plugins/ap-list.css@@")
|
||||
.appendTo("head");
|
||||
}
|
||||
|
||||
window.plugin.apList.setupList = function() {
|
||||
var content = '<div id="ap-list">'
|
||||
+ '<span id="ap-list-side-labels">'
|
||||
+ '<span id="ap-list-eny">'
|
||||
+ '<a href="#" onclick="window.plugin.apList.displayEnemy();return false;">Enemy</a>'
|
||||
+ '</span>'
|
||||
+ '<span id="ap-list-frd">'
|
||||
+ '<a href="#" onclick="window.plugin.apList.displayFriendly();return false;">Friendly</a>'
|
||||
+ '</span>'
|
||||
+ '</span>'
|
||||
+ '<span id="ap-list-reload">'
|
||||
+ '<a href="#" title="Clear list and reload" onclick="window.plugin.apList.disableCache();'
|
||||
+ 'plugin.apList.hideReloadLabel();return false;">↻ R</a>'
|
||||
+ '</span>'
|
||||
+ '<div id="ap-list-table"></div>'
|
||||
+ '<span id="ap-list-misc-info" title="Stats">...</span>'
|
||||
+ '<span id="ap-list-pagination"></span>'
|
||||
+ '</div>';
|
||||
|
||||
$('#sidebar').append(content);
|
||||
$('#ap-list-reload').hide();
|
||||
}
|
||||
|
||||
window.plugin.apList.setupPagination = function() {
|
||||
var content = '<div class="ap-list-center-div">'
|
||||
+ '<div id="ap-list-first-p" class="ap-list-page-control" onclick="plugin.apList.changePage(-1, true);">'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-left ap-list-triangle-left-half"/>'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-left ap-list-triangle-left-half"/>'
|
||||
+ '</div>'
|
||||
+ '<div id="ap-list-next-p" class="ap-list-page-control" onclick="plugin.apList.changePage(-1);">'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-left ap-list-triangle-left-full"/>'
|
||||
+ '</div>'
|
||||
+ '<div id="ap-list-current-p" class="ap-list-page-text">1</div>'
|
||||
+ '<div id="ap-list-page-slash" class="ap-list-page-text">/</div>'
|
||||
+ '<div id="ap-list-total-p" class="ap-list-page-text">1</div>'
|
||||
+ '<div id="ap-list-prev-p" class="ap-list-page-control" onclick="plugin.apList.changePage(1);">'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-right ap-list-triangle-right-full"/>'
|
||||
+ '</div>'
|
||||
+ '<div id="ap-list-last-p" class="ap-list-page-control" onclick="plugin.apList.changePage(1, true);">'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-right ap-list-triangle-right-half"/>'
|
||||
+ '<div class="ap-list-triangle ap-list-triangle-right ap-list-triangle-right-half"/>'
|
||||
+ '</div>'
|
||||
+ '<div class="spacer" style="clear: both;"></div>'// fix collapsion of parent caused by inner div's float:left
|
||||
+ '</div>';
|
||||
$('#ap-list-pagination').html(content);
|
||||
}
|
||||
|
||||
window.plugin.apList.setupMapEvent = function() {
|
||||
map.on('zoomstart', function() {
|
||||
plugin.apList.setupMapEvent.zoomLevelBefore = map.getZoom();
|
||||
// Stop changing cacheBounds if cache enabled
|
||||
if(!plugin.apList.useCachedPortals)
|
||||
plugin.apList.cacheBounds = map.getBounds();
|
||||
});
|
||||
|
||||
map.on('zoomend', function() {
|
||||
// if zooming in and cache not yet enable, enable it
|
||||
if(!plugin.apList.useCachedPortals
|
||||
&& map.getZoom() > plugin.apList.setupMapEvent.zoomLevelBefore) {
|
||||
plugin.apList.enableCache();
|
||||
plugin.apList.showReloadLabel();
|
||||
}
|
||||
});
|
||||
|
||||
map.on('moveend zoomend', function() {
|
||||
// disable cache after out of cache bounds
|
||||
if(plugin.apList.useCachedPortals) {
|
||||
var currentBounds = map.getBounds();
|
||||
if(!plugin.apList.cacheBounds.contains(currentBounds)) {
|
||||
plugin.apList.disableCache();
|
||||
plugin.apList.hideReloadLabel();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.plugin.apList.setupVar();
|
||||
window.plugin.apList.setupSorting();
|
||||
window.plugin.apList.setupTableColumns();
|
||||
window.plugin.apList.setupCSS();
|
||||
window.plugin.apList.setupList();
|
||||
window.plugin.apList.setupPagination();
|
||||
window.plugin.apList.setupMapEvent();
|
||||
window.addHook('mapDataRefreshEnd', window.plugin.apList.handleUpdate);
|
||||
}
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
141
plugins/broken/compute-ap-stats.user.js
Normal file
141
plugins/broken/compute-ap-stats.user.js
Normal file
@ -0,0 +1,141 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-compute-ap-stats@Hollow011
|
||||
// @name IITC plugin: Compute AP statistics
|
||||
// @category Info
|
||||
// @version 0.3.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Displays the per-team AP gains available in the current view.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.compAPStats = function() {};
|
||||
|
||||
window.plugin.compAPStats.setupCallback = function() {
|
||||
// add a new div to the bottom of the sidebar and style it
|
||||
$('#sidebar').append('<div id="available_ap_display"></div>');
|
||||
$('#available_ap_display').css({'color':'#ffce00', 'font-size':'90%', 'padding':'4px 2px'});
|
||||
|
||||
// do an initial calc for sidebar sizing purposes
|
||||
window.plugin.compAPStats.onPositionMove();
|
||||
|
||||
// make the value update when the map data updates
|
||||
window.addHook('mapDataRefreshEnd', window.plugin.compAPStats.onPositionMove);
|
||||
|
||||
}
|
||||
|
||||
window.plugin.compAPStats.onPositionMove = function() {
|
||||
var result = window.plugin.compAPStats.compAPStats();
|
||||
$('#available_ap_display').html('Available AP in this area:<table>'
|
||||
+ '<tr><td>Enlightened:</td><td style="text-align:right">' + digits(result[1]) + '</td></tr>'
|
||||
+ '<tr><td>Resistance:</td><td style="text-align:right">' + digits(result[0]) + '</td></tr>'
|
||||
+ '</table>');
|
||||
}
|
||||
|
||||
window.plugin.compAPStats.missingResonatorAP = function(portal) {
|
||||
var resAP = 0;
|
||||
var missing_resonators = 0;
|
||||
$.each(portal.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso === null) {
|
||||
missing_resonators++;
|
||||
}
|
||||
});
|
||||
if(missing_resonators > 0) {
|
||||
resAP = window.DEPLOY_RESONATOR * missing_resonators;
|
||||
resAP += window.COMPLETION_BONUS;
|
||||
}
|
||||
return(resAP);
|
||||
};
|
||||
|
||||
window.plugin.compAPStats.compAPStats = function() {
|
||||
|
||||
var totalAP_RES = 0;
|
||||
var totalAP_ENL = 0;
|
||||
|
||||
var allResEdges = [];
|
||||
var allResFields = [];
|
||||
var allEnlEdges = [];
|
||||
var allEnlFields = [];
|
||||
|
||||
var displayBounds = map.getBounds();
|
||||
|
||||
// Grab every portal in the viewable area and compute individual AP stats
|
||||
$.each(window.portals, function(ind, portal) {
|
||||
var d = portal.options.details;
|
||||
|
||||
// eliminate offscreen portals (selected, and in padding)
|
||||
if(!displayBounds.contains(portal.getLatLng())) return true;
|
||||
|
||||
var portalStats = getAttackApGain(d);
|
||||
var portalSum = portalStats.resoAp + portalStats.captureAp;
|
||||
|
||||
if (getTeam(d) === TEAM_ENL) {
|
||||
totalAP_RES += portalSum;
|
||||
|
||||
$.each(d.portalV2.linkedEdges||[], function(ind, edge) {
|
||||
if(!edge) return true;
|
||||
allEnlEdges.push(edge.edgeGuid);
|
||||
});
|
||||
|
||||
$.each(d.portalV2.linkedFields||[], function(ind, field) {
|
||||
if(!field) return true;
|
||||
allEnlFields.push(field);
|
||||
});
|
||||
|
||||
totalAP_ENL += window.plugin.compAPStats.missingResonatorAP(d);
|
||||
|
||||
}
|
||||
else if (getTeam(d) === TEAM_RES) {
|
||||
totalAP_ENL += portalSum;
|
||||
|
||||
$.each(d.portalV2.linkedEdges||[], function(ind, edge) {
|
||||
if(!edge) return true;
|
||||
allResEdges.push(edge.edgeGuid);
|
||||
});
|
||||
|
||||
$.each(d.portalV2.linkedFields||[], function(ind, field) {
|
||||
if(!field) return true;
|
||||
allResFields.push(field);
|
||||
});
|
||||
|
||||
totalAP_RES += window.plugin.compAPStats.missingResonatorAP(d);
|
||||
|
||||
} else {
|
||||
// it's a neutral portal, potential for both teams. by definition no fields or edges
|
||||
totalAP_ENL += portalSum;
|
||||
totalAP_RES += portalSum;
|
||||
}
|
||||
});
|
||||
|
||||
// Compute team field AP
|
||||
allResFields = uniqueArray(allResFields);
|
||||
totalAP_ENL += (allResFields.length * DESTROY_FIELD);
|
||||
allEnlFields = uniqueArray(allEnlFields);
|
||||
totalAP_RES += (allEnlFields.length * DESTROY_FIELD);
|
||||
|
||||
// Compute team Link AP
|
||||
allResEdges = uniqueArray(allResEdges);
|
||||
totalAP_ENL += (allResEdges.length * DESTROY_LINK);
|
||||
allEnlEdges = uniqueArray(allEnlEdges);
|
||||
totalAP_RES += (allEnlEdges.length * DESTROY_LINK);
|
||||
|
||||
return [totalAP_RES, totalAP_ENL];
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.plugin.compAPStats.setupCallback();
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
811
plugins/broken/draw-resonators.user.js
Normal file
811
plugins/broken/draw-resonators.user.js
Normal file
@ -0,0 +1,811 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-draw-resonators@xelio
|
||||
// @name IITC plugin: Draw resonators
|
||||
// @category Layer
|
||||
// @version 0.4.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Draw resonators on map. With stylers to highlight resonators with specific criteria.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.drawResonators = function() {};
|
||||
|
||||
|
||||
window.plugin.drawResonators.options;
|
||||
window.plugin.drawResonators.render;
|
||||
|
||||
|
||||
|
||||
//////// Render for handling render of resonators ////////
|
||||
|
||||
// As long as 'window.Render.prototype.createPortalEntity' delete and recreate portal
|
||||
// on any change of data, this resonator render should make resonator create and remove
|
||||
// with portal correctly.
|
||||
//
|
||||
// Resonators will create when
|
||||
// 1.Portal added to map
|
||||
// 2.Zooming in to enable zoom level
|
||||
//
|
||||
// Resonators will remove when
|
||||
// 1.Portal removed from map
|
||||
// 2.Zooming out beyond enable zoom level
|
||||
|
||||
window.plugin.drawResonators.Render = function(options) {
|
||||
this.enableZoomLevel = options['enableZoomLevel'];
|
||||
this.useStyler = '';
|
||||
|
||||
this.stylers = {};
|
||||
this.resonators = {};
|
||||
this.resonatorLayerGroup = new L.LayerGroup();
|
||||
this.addStyler(new window.plugin.drawResonators.Styler());
|
||||
this.beforeZoomLevel = map.getZoom();
|
||||
|
||||
this.portalAdded = this.portalAdded.bind(this);
|
||||
this.createResonatorEntities = this.createResonatorEntities.bind(this);
|
||||
this.deleteResonatorEntities = this.deleteResonatorEntities.bind(this);
|
||||
this.handleResonatorEntitiesBeforeZoom = this.handleResonatorEntitiesBeforeZoom.bind(this);
|
||||
this.handleResonatorEntitiesAfterZoom = this.handleResonatorEntitiesAfterZoom.bind(this);
|
||||
this.handleEnableZoomLevelChange = this.handleEnableZoomLevelChange.bind(this);
|
||||
this.portalSelectionChange = this.portalSelectionChange.bind(this);
|
||||
this.changeStyler = this.changeStyler.bind(this);
|
||||
this.getStylersList = this.getStylersList.bind(this);
|
||||
};
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.registerHook = function() {
|
||||
window.addHook('portalAdded', this.portalAdded);
|
||||
window.addHook('portalSelected', this.portalSelectionChange);
|
||||
window.map.on('zoomstart', this.handleResonatorEntitiesBeforeZoom);
|
||||
window.map.on('zoomend', this.handleResonatorEntitiesAfterZoom);
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.portalAdded = function(data) {
|
||||
var marker = data.portal;
|
||||
var render = this;
|
||||
|
||||
marker.on('add', function() {
|
||||
render.createResonatorEntities(this); // the 'this' in here is the portal.
|
||||
});
|
||||
|
||||
marker.on('remove', function() {
|
||||
render.deleteResonatorEntities(this.options.guid); // the 'this' in here is the portal.
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.createResonatorEntities = function(portal) {
|
||||
// No need to check for existing resonators, as old resonators should be removed with the portal marker.
|
||||
|
||||
if(!this.isResonatorsShow()) return;
|
||||
var portalDetails = portal.options.details;
|
||||
var resonatorsWithConnector = new L.LayerGroup()
|
||||
|
||||
var portalLatLng = [portalDetails.locationE6.latE6/1E6, portalDetails.locationE6.lngE6/1E6];
|
||||
var portalSelected = selectedPortal === portal.options.guid;
|
||||
|
||||
for(var i in portalDetails.resonatorArray.resonators) {
|
||||
resoData = portalDetails.resonatorArray.resonators[i];
|
||||
if(resoData === null) continue;
|
||||
|
||||
var resoLatLng = this.getResonatorLatLng(resoData.distanceToPortal, resoData.slot, portalLatLng);
|
||||
|
||||
var resoMarker = this.createResoMarker(resoData, resoLatLng, portalSelected);
|
||||
var connMarker = this.createConnMarker(resoData, resoLatLng, portalLatLng, portalSelected);
|
||||
|
||||
resonatorsWithConnector.addLayer(resoMarker);
|
||||
resonatorsWithConnector.addLayer(connMarker);
|
||||
}
|
||||
|
||||
resonatorsWithConnector.options = {
|
||||
details: portalDetails.resonatorArray.resonators,
|
||||
guid: portal.options.guid
|
||||
};
|
||||
|
||||
this.resonators[portal.options.guid] = resonatorsWithConnector;
|
||||
this.resonatorLayerGroup.addLayer(resonatorsWithConnector);
|
||||
|
||||
// bring portal in front of resonator connector
|
||||
portal.bringToFront();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.createResoMarker = function(resoData, resoLatLng, portalSelected) {
|
||||
var resoProperty = this.getStyler().getResonatorStyle(resoData, portalSelected);
|
||||
resoProperty.type = 'resonator';
|
||||
resoProperty.details = resoData;
|
||||
var reso = L.circleMarker(resoLatLng, resoProperty);
|
||||
return reso;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.createConnMarker = function(resoData, resoLatLng, portalLatLng, portalSelected) {
|
||||
var connProperty = this.getStyler().getConnectorStyle(resoData, portalSelected);
|
||||
connProperty.type = 'connector';
|
||||
connProperty.details = resoData;
|
||||
var conn = L.polyline([portalLatLng, resoLatLng], connProperty);
|
||||
return conn;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.getResonatorLatLng = function(dist, slot, portalLatLng) {
|
||||
// offset in meters
|
||||
var dn = dist*SLOT_TO_LAT[slot];
|
||||
var de = dist*SLOT_TO_LNG[slot];
|
||||
|
||||
// Coordinate offset in radians
|
||||
var dLat = dn/EARTH_RADIUS;
|
||||
var dLon = de/(EARTH_RADIUS*Math.cos(Math.PI/180*portalLatLng[0]));
|
||||
|
||||
// OffsetPosition, decimal degrees
|
||||
var lat0 = portalLatLng[0] + dLat * 180/Math.PI;
|
||||
var lon0 = portalLatLng[1] + dLon * 180/Math.PI;
|
||||
|
||||
return [lat0, lon0];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.deleteResonatorEntities = function(portalGuid) {
|
||||
if (!(portalGuid in this.resonators)) return;
|
||||
|
||||
var r = this.resonators[portalGuid];
|
||||
this.resonatorLayerGroup.removeLayer(r);
|
||||
delete this.resonators[portalGuid];
|
||||
}
|
||||
|
||||
// Save zoom level before zoom, use to determine redraw of resonator
|
||||
window.plugin.drawResonators.Render.prototype.handleResonatorEntitiesBeforeZoom = function() {
|
||||
this.beforeZoomLevel = map.getZoom();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.handleResonatorEntitiesAfterZoom = function() {
|
||||
if(!this.isResonatorsShow()) {
|
||||
this.clearAllResonators();
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw all resonators if they were not drawn
|
||||
if(!this.isResonatorsShowBeforeZoom()) {
|
||||
this.drawAllResonators();
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.handleEnableZoomLevelChange = function(zoomLevel) {
|
||||
this.enableZoomLevel = zoomLevel;
|
||||
|
||||
if(!this.isResonatorsShow()) {
|
||||
this.clearAllResonators();
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw all resonators if they were not drawn
|
||||
if(!Object.keys(this.resonators).length > 0) {
|
||||
this.drawAllResonators();
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.clearAllResonators = function() {
|
||||
this.resonatorLayerGroup.clearLayers();
|
||||
this.resonators = {};
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.drawAllResonators = function() {
|
||||
var render = this;
|
||||
|
||||
// loop through level of portals, only draw if the portal is shown on map
|
||||
for (var guid in window.portals) {
|
||||
var portal = window.portals[guid];
|
||||
// FIXME: need to find a proper way to check if a portal is added to the map without depending on leaflet internals
|
||||
// (and without depending on portalsLayers either - that's IITC internal)
|
||||
if (portal._map) {
|
||||
render.createResonatorEntities(portal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.portalSelectionChange = function(data) {
|
||||
this.toggleSelectedStyle(data.selectedPortalGuid);
|
||||
this.toggleSelectedStyle(data.unselectedPortalGuid);
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.toggleSelectedStyle = function(portalGuid) {
|
||||
if (!(portalGuid in this.resonators)) return;
|
||||
|
||||
var render = this;
|
||||
var portalSelected = selectedPortal === portalGuid;
|
||||
var r = this.resonators[portalGuid];
|
||||
|
||||
r.eachLayer(function(entity) {
|
||||
var style;
|
||||
if(entity.options.type === 'resonator') {
|
||||
style = render.getStyler().getResonatorStyle(entity.options.details, portalSelected);
|
||||
} else {
|
||||
style = render.getStyler().getConnectorStyle(entity.options.details, portalSelected);
|
||||
}
|
||||
|
||||
entity.setStyle(style);
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.addStyler = function(styler) {
|
||||
this.stylers[styler.name] = styler;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.getStylersList = function() {
|
||||
return Object.keys(this.stylers);
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.getStyler = function() {
|
||||
var stylerName = this.useStyler in this.stylers ? this.useStyler : 'Default';
|
||||
return this.stylers[stylerName];
|
||||
}
|
||||
|
||||
// Change if styler need change, and redraw all resonators using new styler
|
||||
window.plugin.drawResonators.Render.prototype.changeStyler = function(name) {
|
||||
if (name === this.useStyler) return;
|
||||
for(stylerName in this.stylers) {
|
||||
if(stylerName === name) {
|
||||
if(this.stylers[this.useStyler]) this.stylers[this.useStyler].onDisableFunc();
|
||||
this.useStyler = stylerName;
|
||||
this.stylers[this.useStyler].onEnableFunc();
|
||||
this.clearAllResonators();
|
||||
this.drawAllResonators();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.refreshStyler = function() {
|
||||
this.clearAllResonators();
|
||||
this.drawAllResonators();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.isResonatorsShow = function() {
|
||||
return map.getZoom() >= this.enableZoomLevel;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.isResonatorsShowBeforeZoom = function() {
|
||||
return this.beforeZoomLevel >= this.enableZoomLevel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// Styler for getting resonator and connector style ////////
|
||||
|
||||
|
||||
|
||||
window.plugin.drawResonators.Styler = function(options) {
|
||||
options = options || {};
|
||||
this.name = options['name'] || 'Default';
|
||||
this.otherOptions = options['otherOptions'];
|
||||
this.getResonatorStyle = options['resonatorStyleFunc'] || this.defaultResonatorStyle;
|
||||
this.getConnectorStyle = options['connectorStyleFunc'] || this.defaultConnectorStyle;
|
||||
this.onEnableFunc = options['onEnableFunc'] || function() {};
|
||||
this.onDisableFunc = options['onDisableFunc'] || function() {};
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_SELECTED = {
|
||||
color: '#fff',
|
||||
weight: 1.1,
|
||||
radius: 4,
|
||||
opacity: 1,
|
||||
clickable: false};
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_NON_SELECTED = {
|
||||
color: '#aaa',
|
||||
weight: 1,
|
||||
radius: 3,
|
||||
opacity: 1,
|
||||
clickable: false};
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_LINE_SELECTED = {
|
||||
opacity: 0.7,
|
||||
weight: 3,
|
||||
color: '#FFA000',
|
||||
dashArray: '0,10' + (new Array(25).join(',8,4')),
|
||||
fill: false,
|
||||
clickable: false};
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_LINE_NON_SELECTED = {
|
||||
opacity: 0.25,
|
||||
weight: 2,
|
||||
color: '#FFA000',
|
||||
dashArray: '0,10' + (new Array(25).join(',8,4')),
|
||||
fill: false,
|
||||
clickable: false};
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.defaultResonatorStyle = function(resoDetail, selected) {
|
||||
var resoSharedStyle = selected
|
||||
? this.DEFAULT_OPTIONS_RESONATOR_SELECTED
|
||||
: this.DEFAULT_OPTIONS_RESONATOR_NON_SELECTED;
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level],
|
||||
}, resoSharedStyle);
|
||||
|
||||
return resoStyle;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.defaultConnectorStyle = function(resoDetail, selected) {
|
||||
var connStyle = selected
|
||||
? this.DEFAULT_OPTIONS_RESONATOR_LINE_SELECTED
|
||||
: this.DEFAULT_OPTIONS_RESONATOR_LINE_NON_SELECTED;
|
||||
|
||||
return connStyle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// Options for storing and loading options ////////
|
||||
|
||||
|
||||
|
||||
window.plugin.drawResonators.Options = function() {
|
||||
this._options = {};
|
||||
this._callbacks = {};
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.addCallback = function(name, callback) {
|
||||
if (!this._callbacks[name]) {
|
||||
this._callbacks[name] = [];
|
||||
}
|
||||
this._callbacks[name].push(callback);
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.newOption = function(name, defaultValue) {
|
||||
this._options[name] = this.loadLocal(this.getStorageKey(name), defaultValue)
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.getOption = function(name) {
|
||||
return this._options[name];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.removeOption = function(name) {
|
||||
delete this._options[name];
|
||||
delete this._callbacks[name];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.changeOption = function(name, value) {
|
||||
if(!(name in this._options)) return false;
|
||||
if(value === this._options[name]) return false;
|
||||
|
||||
this._options[name] = value;
|
||||
this.storeLocal(this.getStorageKey(name), this._options[name]);
|
||||
|
||||
if (this._callbacks[name] !== null) {
|
||||
for(var i in this._callbacks[name]) {
|
||||
this._callbacks[name][i](value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.getStorageKey = function(name) {
|
||||
return 'plugin-drawResonators-option-' + name;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.loadLocal = function(key, defaultValue) {
|
||||
var objectJSON = localStorage[key];
|
||||
if(objectJSON) {
|
||||
return JSON.parse(objectJSON);
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.storeLocal = function(key, value) {
|
||||
if(typeof(value) !== 'undefined' && value !== null) {
|
||||
localStorage[key] = JSON.stringify(value);
|
||||
} else {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// Dialog
|
||||
|
||||
window.plugin.drawResonators.Dialog = function() {
|
||||
this._dialogEntries = {};
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.addLink = function() {
|
||||
$('#toolbox').append('<a id="draw-reso-show-dialog" onclick="window.plugin.drawResonators.dialog.show();">Resonators</a> ');
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.addEntry = function(name, dialogEntry) {
|
||||
this._dialogEntries[name] = dialogEntry;
|
||||
this.change();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.removeEntry = function(name) {
|
||||
delete this._dialogEntries[name];
|
||||
this.change();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.show = function() {
|
||||
window.dialog({html: this.getDialogHTML(), title: 'Resonators', modal: true, id: 'draw-reso-setting'});
|
||||
|
||||
// Attach entries event
|
||||
for(var name in this._dialogEntries) {
|
||||
var events = this._dialogEntries[name].getOnEvents();
|
||||
for(var i in events) {
|
||||
var event = events[i];
|
||||
$('#draw-reso-dialog').on(event.event, '#' + event.id, event.callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.change = function() {
|
||||
if($('#draw-reso-dialog').length > 0) this.show();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.getDialogHTML = function() {
|
||||
var html = '<div id="draw-reso-dialog">'
|
||||
for(var name in this._dialogEntries) {
|
||||
html += '<div>'
|
||||
+ this._dialogEntries[name].getHTML()
|
||||
+ '</div>';
|
||||
}
|
||||
html += '</div>';
|
||||
return html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// ListDialogEntry
|
||||
|
||||
|
||||
|
||||
window.plugin.drawResonators.ListDialogEntry = function(options) {
|
||||
this._name = options['name'];
|
||||
this._label = options['label'];
|
||||
this._valueFunc = options['valueFunc'];
|
||||
this._valuesList = options['valuesList'];
|
||||
this._valuesListFunc = options['valuesListFunc'];
|
||||
this._onChangeCallback = options['onChangeCallback'];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.ListDialogEntry.prototype.getHTML = function() {
|
||||
var curValue = this._valueFunc();
|
||||
var valuesList = this._valuesList ? this._valuesList : this._valuesListFunc();
|
||||
var html = '<label for="' + this.getSelectId() + '">'
|
||||
+ this._label + ': '
|
||||
+ '</label>'
|
||||
+ '<select id="' + this.getSelectId() + '">';
|
||||
|
||||
var noLabel = valuesList instanceof Array;
|
||||
for(var label in valuesList) {
|
||||
var selected = valuesList[label] === curValue;
|
||||
html += '<option value="' + valuesList[label] + '" '
|
||||
+ (selected ? 'selected="selected"' : '')
|
||||
+'>'
|
||||
+ (noLabel ? valuesList[label] : label)
|
||||
+ '</option>';
|
||||
}
|
||||
|
||||
html += '</select>';
|
||||
return html;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.ListDialogEntry.prototype.getOnEvents = function() {
|
||||
return [{'event': 'change',
|
||||
'id': this.getSelectId(),
|
||||
'callback': this._onChangeCallback
|
||||
}];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.ListDialogEntry.prototype.getSelectId = function() {
|
||||
return 'draw-reso-option-' + this._name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// TextboxDialogEntry
|
||||
|
||||
|
||||
window.plugin.drawResonators.TextboxDialogEntry = function(options) {
|
||||
this._name = options['name'];
|
||||
this._label = options['label'];
|
||||
this._valueFunc = options['valueFunc'];
|
||||
this._onChangeCallback = options['onChangeCallback'];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.TextboxDialogEntry.prototype.getHTML = function() {
|
||||
var curValue = this._valueFunc();
|
||||
var html = '<label for="' + this.getInputId() + '">'
|
||||
+ this._label + ': '
|
||||
+ '</label>'
|
||||
+ '<input type="text" size="20" id="' + this.getInputId() + '" '
|
||||
+ 'value="' + curValue + '" />';
|
||||
return html;
|
||||
}
|
||||
|
||||
|
||||
window.plugin.drawResonators.TextboxDialogEntry.prototype.getOnEvents = function() {
|
||||
return [{'event': 'change',
|
||||
'id': this.getInputId(),
|
||||
'callback': this._onChangeCallback
|
||||
}];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.TextboxDialogEntry.prototype.getInputId = function() {
|
||||
return 'draw-reso-option-' + this._name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.plugin.drawResonators.setupStyler = function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
|
||||
var highlightedReso = {color: '#fff', weight: 2, radius: 4, opacity: 1, clickable: false};
|
||||
var normalReso = {color: '#aaa', weight: 1, radius: 3, opacity: 1, clickable: false};
|
||||
var selectedReso = {color: '#eee', weight: 1.1, radius: 4, opacity: 1, clickable: false};
|
||||
var highlightedConn = {opacity: 0.7, weight: 3, color: '#FFA000', dashArray: '0,10,999', color: '#FFA000', fill: false, clickable: false};
|
||||
var normalConn = {opacity: 0.25, weight: 2, color: '#FFA000', dashArray: '0,10' + (new Array(25).join(',8,4')), fill: false, clickable: false};
|
||||
var selectedConn = {opacity: 0.7, weight: 3, color: '#FFA000', dashArray: '0,10' + (new Array(25).join(',8,4')), fill: false, clickable: false};
|
||||
|
||||
// Styler for highlighting resonators deployed by me
|
||||
var myReso = {
|
||||
name: 'Highlight my resonators',
|
||||
otherOptions: {
|
||||
'highlightedReso' : highlightedReso,
|
||||
'normalReso' : normalReso,
|
||||
'selectedReso' : selectedReso,
|
||||
'highlightedConn' : highlightedConn,
|
||||
'normalConn' : normalConn,
|
||||
'selectedConn' : selectedConn
|
||||
},
|
||||
resonatorStyleFunc: function(resoDetail, selected) {
|
||||
var mine = resoDetail.ownerGuid === PLAYER.guid;
|
||||
var resoSharedStyle = mine
|
||||
? this.otherOptions.highlightedReso
|
||||
: (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso);
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] * (mine ? 1 : 0.75)
|
||||
}, resoSharedStyle);
|
||||
return resoStyle;
|
||||
},
|
||||
connectorStyleFunc: function(resoDetail, selected) {
|
||||
var mine = resoDetail.ownerGuid === PLAYER.guid;
|
||||
var connStyle = mine
|
||||
? this.otherOptions.highlightedConn
|
||||
: (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn);
|
||||
return connStyle;
|
||||
}
|
||||
};
|
||||
|
||||
thisPlugin.render.addStyler(new thisPlugin.Styler(myReso));
|
||||
|
||||
// Styler for highlighting L8 resonators
|
||||
var l8Reso = {
|
||||
name: 'Highlight L8 resonators',
|
||||
otherOptions: {
|
||||
'highlightedReso' : highlightedReso,
|
||||
'normalReso' : normalReso,
|
||||
'selectedReso' : selectedReso,
|
||||
'highlightedConn' : highlightedConn,
|
||||
'normalConn' : normalConn,
|
||||
'selectedConn' : selectedConn
|
||||
},
|
||||
resonatorStyleFunc: function(resoDetail, selected) {
|
||||
var l8 = resoDetail.level === 8;
|
||||
var resoSharedStyle = l8
|
||||
? this.otherOptions.highlightedReso
|
||||
: (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso);
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] * (l8 ? 1 : 0.75)
|
||||
}, resoSharedStyle);
|
||||
return resoStyle;
|
||||
},
|
||||
connectorStyleFunc: function(resoDetail, selected) {
|
||||
var l8 = resoDetail.level === 8;
|
||||
var connStyle = l8
|
||||
? this.otherOptions.highlightedConn
|
||||
: (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn);
|
||||
return connStyle;
|
||||
}
|
||||
};
|
||||
|
||||
thisPlugin.render.addStyler(new thisPlugin.Styler(l8Reso));
|
||||
|
||||
// Styler for highlighting resonators with less than X% energy
|
||||
var lessThanXPctReso = {
|
||||
name: 'Highlight < X% resonators',
|
||||
otherOptions: {
|
||||
'highlightedReso': highlightedReso,
|
||||
'normalReso': normalReso,
|
||||
'selectedReso': selectedReso,
|
||||
'highlightedConn': highlightedConn,
|
||||
'normalConn': normalConn,
|
||||
'selectedConn': selectedConn,
|
||||
'pct': 15,
|
||||
'dialogEntry': new thisPlugin.TextboxDialogEntry({
|
||||
name: 'resoLessThanPct-pct',
|
||||
label: 'Percentage',
|
||||
valueFunc: function() {return thisPlugin.options.getOption('styler-resoLessThanPct-pct')},
|
||||
onChangeCallback: function(event) {thisPlugin.options.changeOption('styler-resoLessThanPct-pct', parseInt(event.target.value));}
|
||||
})
|
||||
},
|
||||
resonatorStyleFunc: function(resoDetail, selected) {
|
||||
var highlight = (resoDetail.energyTotal * 100) < (RESO_NRG[resoDetail.level] * this.otherOptions.pct);
|
||||
var resoSharedStyle = highlight
|
||||
? this.otherOptions.highlightedReso
|
||||
: (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso);
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level]
|
||||
}, resoSharedStyle);
|
||||
return resoStyle;
|
||||
},
|
||||
connectorStyleFunc: function(resoDetail, selected) {
|
||||
var highlight = (resoDetail.energyTotal * 100) < (RESO_NRG[resoDetail.level] * this.otherOptions.pct);
|
||||
var connStyle = highlight
|
||||
? this.otherOptions.highlightedConn
|
||||
: (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn);
|
||||
return connStyle;
|
||||
},
|
||||
onEnableFunc: function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
var thisStyler = this;
|
||||
// Add option
|
||||
thisPlugin.options.newOption('styler-resoLessThanPct-pct', 15);
|
||||
thisPlugin.options.addCallback('styler-resoLessThanPct-pct', function(value) {
|
||||
thisStyler.otherOptions.pct = value;
|
||||
thisPlugin.render.refreshStyler();
|
||||
});
|
||||
thisStyler.otherOptions.pct = thisPlugin.options.getOption('styler-resoLessThanPct-pct');
|
||||
// Add dialog entry
|
||||
thisPlugin.dialog.addEntry('resoLessThanPct-pct', this.otherOptions.dialogEntry);
|
||||
},
|
||||
onDisableFunc: function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
// Remove option
|
||||
thisPlugin.options.removeOption('styler-resoLessThanPct-pct');
|
||||
// Remove dialog entry
|
||||
thisPlugin.dialog.removeEntry('resoLessThanPct-pct');
|
||||
}
|
||||
};
|
||||
|
||||
thisPlugin.render.addStyler(new thisPlugin.Styler(lessThanXPctReso));
|
||||
|
||||
// Styler for highlighting resonators deployed by specific player
|
||||
var resoOfSpecificPlayer = {
|
||||
name: 'Highlight resonators by player',
|
||||
otherOptions: {
|
||||
'highlightedReso': highlightedReso,
|
||||
'normalReso': normalReso,
|
||||
'selectedReso': selectedReso,
|
||||
'highlightedConn': highlightedConn,
|
||||
'normalConn': normalConn,
|
||||
'selectedConn': selectedConn,
|
||||
'player': '',
|
||||
'playerGuid': '',
|
||||
'dialogEntry': new thisPlugin.TextboxDialogEntry({
|
||||
name: 'resoOfSpecificPlayer-player',
|
||||
label: 'Player name',
|
||||
valueFunc: function() {return thisPlugin.options.getOption('styler-resoOfSpecificPlayer-player')},
|
||||
onChangeCallback: function(event) {thisPlugin.options.changeOption('styler-resoOfSpecificPlayer-player', event.target.value);}
|
||||
})
|
||||
},
|
||||
resonatorStyleFunc: function(resoDetail, selected) {
|
||||
var highlight = resoDetail.ownerGuid === this.otherOptions.playerGuid;
|
||||
var resoSharedStyle = highlight
|
||||
? this.otherOptions.highlightedReso
|
||||
: (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso);
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] * (highlight ? 1 : 0.75)
|
||||
}, resoSharedStyle);
|
||||
return resoStyle;
|
||||
},
|
||||
connectorStyleFunc: function(resoDetail, selected) {
|
||||
var highlight = resoDetail.ownerGuid === this.otherOptions.playerGuid;
|
||||
var connStyle = highlight
|
||||
? this.otherOptions.highlightedConn
|
||||
: (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn);
|
||||
return connStyle;
|
||||
},
|
||||
onEnableFunc: function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
var thisStyler = this;
|
||||
// Add option
|
||||
thisPlugin.options.newOption('styler-resoOfSpecificPlayer-player', '');
|
||||
thisPlugin.options.addCallback('styler-resoOfSpecificPlayer-player', function(value) {
|
||||
thisStyler.otherOptions.player = value;
|
||||
thisStyler.otherOptions.playerGuid = window.playerNameToGuid(value);
|
||||
thisPlugin.render.refreshStyler();
|
||||
});
|
||||
thisStyler.otherOptions.player = thisPlugin.options.getOption('styler-resoOfSpecificPlayer-player');
|
||||
thisStyler.otherOptions.playerGuid = window.playerNameToGuid(thisStyler.otherOptions.player);
|
||||
// Add dialog entry
|
||||
thisPlugin.dialog.addEntry('resoOfSpecificPlayer-player', this.otherOptions.dialogEntry);
|
||||
},
|
||||
onDisableFunc: function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
// Remove option
|
||||
thisPlugin.options.removeOption('styler-resoOfSpecificPlayer-player');
|
||||
// Remove dialog entry
|
||||
thisPlugin.dialog.removeEntry('resoOfSpecificPlayer-player');
|
||||
}
|
||||
};
|
||||
|
||||
thisPlugin.render.addStyler(new thisPlugin.Styler(resoOfSpecificPlayer));
|
||||
|
||||
thisPlugin.render.changeStyler(thisPlugin.options.getOption('useStyler'));
|
||||
}
|
||||
|
||||
|
||||
window.plugin.drawResonators.setupOptions = function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
// Initialize options
|
||||
thisPlugin.options = new thisPlugin.Options();
|
||||
thisPlugin.options.newOption('enableZoomLevel', 17);
|
||||
thisPlugin.options.newOption('useStyler', 'Default');
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.setupDialog = function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
// Initialize dialog
|
||||
thisPlugin.dialog = new thisPlugin.Dialog();
|
||||
|
||||
var enableZoomLevelDialogEntryOptions = {
|
||||
name: 'enable-zoom-level',
|
||||
label: 'Enable zoom level',
|
||||
valueFunc: function() {return thisPlugin.options.getOption('enableZoomLevel')},
|
||||
valuesList: {'15':15, '16':16, '17':17, '18':18, '19':19, '20':20, 'None':99},
|
||||
onChangeCallback: function(event) {thisPlugin.options.changeOption('enableZoomLevel', parseInt(event.target.value));}
|
||||
};
|
||||
var enableZoomLevelDialogEntry = new thisPlugin.ListDialogEntry(enableZoomLevelDialogEntryOptions);
|
||||
thisPlugin.dialog.addEntry('enable-zoom-level', enableZoomLevelDialogEntry);
|
||||
|
||||
var stylerDialogEntryOptions = {
|
||||
name: 'use-styler',
|
||||
label: 'Styler',
|
||||
valueFunc: function() {return thisPlugin.options.getOption('useStyler')},
|
||||
valuesListFunc: thisPlugin.render.getStylersList,
|
||||
onChangeCallback: function(event) {thisPlugin.options.changeOption('useStyler', event.target.value);}
|
||||
};
|
||||
var stylerDialogEntry = new thisPlugin.ListDialogEntry(stylerDialogEntryOptions);
|
||||
thisPlugin.dialog.addEntry('use-styler', stylerDialogEntry);
|
||||
|
||||
thisPlugin.dialog.addLink();
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
|
||||
// Initialize options
|
||||
thisPlugin.setupOptions();
|
||||
|
||||
// Initialize render
|
||||
var renderOptions = {'enableZoomLevel': thisPlugin.options.getOption('enableZoomLevel')};
|
||||
|
||||
thisPlugin.render = new thisPlugin.Render(renderOptions);
|
||||
|
||||
// callback run at option change
|
||||
thisPlugin.options.addCallback('enableZoomLevel', thisPlugin.render.handleEnableZoomLevelChange);
|
||||
thisPlugin.options.addCallback('useStyler', thisPlugin.render.changeStyler);
|
||||
|
||||
// Initialize Dialog
|
||||
thisPlugin.setupDialog();
|
||||
// Initialize styler
|
||||
thisPlugin.setupStyler();
|
||||
|
||||
thisPlugin.render.registerHook();
|
||||
window.addLayerGroup('Resonators', thisPlugin.render.resonatorLayerGroup, true);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
173
plugins/broken/favorite-portals.user.js
Normal file
173
plugins/broken/favorite-portals.user.js
Normal file
@ -0,0 +1,173 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-favorite-portals@soulBit
|
||||
// @name IITC plugin: Favorite Portals
|
||||
// @category Obsolete
|
||||
// @version 0.2.0.@@DATETIMEVERSION@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] DEPRECATED. Please use "Bookmarks for maps and portals" instead.
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
window.plugin.favoritePortals = function() {};
|
||||
|
||||
window.plugin.favoritePortals.portalList = {};
|
||||
window.plugin.favoritePortals.LOCAL_STORAGE_KEY = "plugin-favorite-portals";
|
||||
window.plugin.favoritePortals.hasLocalStorage = ('localStorage' in window && window['localStorage'] !== null);
|
||||
|
||||
window.plugin.favoritePortals.onDetailsUpdated = function(data) {
|
||||
$('.linkdetails').prepend("<div title='Favorite this portal' class='toggle-favorite-portal' onclick='window.plugin.favoritePortals.togglePortal()' />");
|
||||
if(window.plugin.favoritePortals.portalList[window.selectedPortal]) {
|
||||
$('.toggle-favorite-portal').addClass( 'portal-on' );
|
||||
window.plugin.favoritePortals.portalList[window.selectedPortal] = window.portals[window.selectedPortal].options;
|
||||
window.plugin.favoritePortals.savePortals();
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.display = function() {
|
||||
var output = '';
|
||||
|
||||
if (!window.plugin.favoritePortals.hasLocalStorage) {
|
||||
output += "Favorite portals cannot save any data, please try another browser that supports 'localStorage'.";
|
||||
} else {
|
||||
if ($.isEmptyObject(window.plugin.favoritePortals.portalList)) {
|
||||
output += "No portals have been marked as favorite, click the blue square in the bottom left corner of the portal details to save one.";
|
||||
} else {
|
||||
output += "<div class='header'>Portal list (values not current till portal on screen):</div>";
|
||||
output += "<div class='portal-list-container'>";
|
||||
|
||||
var portals = [], dataChanged = false, portalData;
|
||||
$.each( window.plugin.favoritePortals.portalList, function(i, portal) {
|
||||
if(window.portals[i]) {
|
||||
dataChanged = true;
|
||||
window.plugin.favoritePortals.portalList[ i ] = window.portals[i].options;
|
||||
}
|
||||
portalData = (window.portals[i]) ? window.portals[i].options : portal;
|
||||
portals.push({'guid': i, 'portalData': portalData});
|
||||
});
|
||||
if(dataChanged)
|
||||
window.plugin.favoritePortals.savePortals();
|
||||
|
||||
portals.sort(function(a,b) {
|
||||
var nameA = a.portalData.details.portalV2.descriptiveText.TITLE.toLowerCase();
|
||||
var nameB = b.portalData.details.portalV2.descriptiveText.TITLE.toLowerCase();
|
||||
return (nameA < nameB) ? -1 : (nameA > nameB) ? 1 : 0;
|
||||
});
|
||||
|
||||
output += "<ol>";
|
||||
var teamName, energy;
|
||||
$.each(portals, function(i, portal) {
|
||||
portalData = portal.portalData;
|
||||
output += "<li name='" + portal.guid + "'>";
|
||||
|
||||
output += "<a class='delete-favorite-portal' title='Delete favorite?' onclick='window.plugin.favoritePortals.onDelete(" + '"' + portal.guid + '"' + ");return false'>X</a>";
|
||||
output += "<a onclick='window.plugin.favoritePortals.onPortalClicked(" + ' "' + portal.guid + '", [' + (portalData.details.locationE6.latE6 / 1000000) + "," + (portal.portalData.details.locationE6.lngE6 / 1000000) + "]);return false'>" + portalData.details.portalV2.descriptiveText.TITLE + "</a>";
|
||||
teamName = portalData.details.controllingTeam.team;
|
||||
output += " - L" + Math.floor( portalData.level );
|
||||
energy = Math.floor( window.getCurrentPortalEnergy(portalData.details) / window.getPortalEnergy(portalData.details) * 100 );
|
||||
if(!isNaN(energy))
|
||||
output += " @" + energy + "%";
|
||||
output += ": " + ( (teamName === "ALIENS") ? "Enlightened" : teamName[0] + teamName.slice(1).toLowerCase() );
|
||||
if(portalData.details.portalV2.linkedEdges.length > 0 || portalData.details.portalV2.linkedFields.length > 0)
|
||||
output += ", " + portalData.details.portalV2.linkedEdges.length + " links & " + portalData.details.portalV2.linkedFields.length + " fields";
|
||||
output += "</li>";
|
||||
});
|
||||
|
||||
output += "</ol>"
|
||||
output += "</div>";
|
||||
}
|
||||
}
|
||||
|
||||
window.dialog({'html': "<div id='favorite-portal-list'>" + output + "</div>", 'title': 'Favorite portals', 'id': 'favorite-portals'});
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.onDelete = function(guid) {
|
||||
delete window.plugin.favoritePortals.portalList[ guid ];
|
||||
if(window.selectedPortal && window.selectedPortal === guid)
|
||||
$('.toggle-favorite-portal').removeClass( 'portal-on' ).addClass( 'portal-off' );
|
||||
$("li[name='" + guid + "']").remove();
|
||||
window.plugin.favoritePortals.savePortals();
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.onPortalClicked = function(guid, coords) {
|
||||
window.zoomToAndShowPortal(guid, coords);
|
||||
$('#dialog-favorite-portals').dialog('close');
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.togglePortal = function() {
|
||||
if(window.plugin.favoritePortals.portalList[window.selectedPortal]) {
|
||||
$('.toggle-favorite-portal').removeClass('portal-on').addClass('portal-off');
|
||||
delete window.plugin.favoritePortals.portalList[ window.selectedPortal ];
|
||||
} else {
|
||||
$('.toggle-favorite-portal').removeClass('portal-off').addClass('portal-on');
|
||||
window.plugin.favoritePortals.portalList[window.selectedPortal] = window.portals[window.selectedPortal].options;
|
||||
}
|
||||
window.plugin.favoritePortals.savePortals();
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.savePortals = function() {
|
||||
var portalsObject = {'portals': window.plugin.favoritePortals.portalList};
|
||||
var portalListJSON = JSON.stringify(portalsObject);
|
||||
localStorage[window.plugin.favoritePortals.LOCAL_STORAGE_KEY] = portalListJSON;
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.loadPortals = function() {
|
||||
var portalListJSON = localStorage[window.plugin.favoritePortals.LOCAL_STORAGE_KEY];
|
||||
if(!portalListJSON) return;
|
||||
var portalsObject = JSON.parse(portalListJSON);
|
||||
window.plugin.favoritePortals.portalList = portalsObject.portals;
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.setup = function() {
|
||||
window.plugin.favoritePortals.loadPortals();
|
||||
window.addHook('portalDetailsUpdated', window.plugin.favoritePortals.onDetailsUpdated);
|
||||
$('#toolbox').append("<a onclick='window.plugin.favoritePortals.display()' title='Create a list of favorite portals'>Favorite Portals</a>");
|
||||
$("<style>").prop("type", "text/css").html(".toggle-favorite-portal {\
|
||||
width: 13px;\
|
||||
height: 13px;\
|
||||
margin-left: 10px;\
|
||||
vertical-align: middle;\
|
||||
display: inline-block;\
|
||||
cursor: pointer;\
|
||||
border: 1px solid #20A8B1;\
|
||||
}\
|
||||
.portal-on {\
|
||||
background-color: #20A8B1;\
|
||||
}\
|
||||
.portal-off {\
|
||||
}\
|
||||
.linkdetails {\
|
||||
margin-bottom: 5px;\
|
||||
}\
|
||||
.delete-favorite-portal {\
|
||||
width: 10px;\
|
||||
height: 10px;\
|
||||
color: #FFCC00;\
|
||||
border: 2px solid #20A8B1;\
|
||||
margin-right: 10px;\
|
||||
padding-left: 3px;\
|
||||
padding-right: 3px;\
|
||||
font-weight: bolder;\
|
||||
}\
|
||||
#favorite-portal-list {\
|
||||
padding: 5px;\
|
||||
}\
|
||||
#favorite-portal-list li {\
|
||||
line-height: 1.8;\
|
||||
}").appendTo("head");
|
||||
};
|
||||
|
||||
var setup = window.plugin.favoritePortals.setup;
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
111
plugins/broken/ipas-link.user.js
Normal file
111
plugins/broken/ipas-link.user.js
Normal file
@ -0,0 +1,111 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-ipas-link@graphracer
|
||||
// @name IITC Plugin: simulate an attack on portal
|
||||
// @category Portal Info
|
||||
// @version 0.2.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/xosofox/IPAS
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Adds a link to the portal details to open the portal in IPAS - Ingress Portal Attack Simulator on http://ipas.graphracer.com
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.ipasLink = function() {};
|
||||
|
||||
window.plugin.ipasLink.setupCallback = function() {
|
||||
addHook('portalDetailsUpdated', window.plugin.ipasLink.addLink);
|
||||
}
|
||||
|
||||
window.plugin.ipasLink.addLink = function(d) {
|
||||
$('.linkdetails').append('<aside><a href="http://ipas.graphracer.com/index.html#' + window.plugin.ipasLink.getHash(d.portalDetails) + '" target="ipaswindow" title="Use IPAS to simulate an attack on this portal">Simulate attack</a></aside>');
|
||||
}
|
||||
|
||||
window.plugin.ipasLink.getHash = function (d) {
|
||||
var hashParts = [];
|
||||
$.each(d.resonatorArray.resonators, function (ind, reso) {
|
||||
if (reso) {
|
||||
hashParts.push(reso.level + "," + reso.distanceToPortal + "," + reso.energyTotal);
|
||||
} else {
|
||||
hashParts.push("1,20,0");
|
||||
}
|
||||
});
|
||||
var resos = hashParts.join(";");
|
||||
|
||||
hashParts = [];
|
||||
$.each(d.portalV2.linkedModArray, function (ind, mod) {
|
||||
// s - shields
|
||||
// h - heat sink
|
||||
// i - intentionally left in
|
||||
// t - turret
|
||||
//
|
||||
// f - force amp
|
||||
// m - multi-hack
|
||||
// l - link-amp
|
||||
//
|
||||
var modCodes = {
|
||||
"RES_SHIELD": "s",
|
||||
"HEATSINK": "h",
|
||||
"TURRET": "t",
|
||||
"FORCE_AMP": "f",
|
||||
"MULTIHACK": "m",
|
||||
"LINK_AMPLIFIER": "l"
|
||||
}
|
||||
|
||||
var mc = "0";
|
||||
if (mod) {
|
||||
if (mod.type in modCodes) {
|
||||
mc = modCodes[mod.type] + mod.rarity.charAt(0).toLowerCase();
|
||||
|
||||
//special for shields to distinguish old/new mitigation
|
||||
if (mod.type == "RES_SHIELD") {
|
||||
mc += mod.stats.MITIGATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
hashParts.push(mc);
|
||||
});
|
||||
var shields = hashParts.join(",");
|
||||
|
||||
var linkParts = [];
|
||||
var edges = d.portalV2.linkedEdges;
|
||||
|
||||
var portalL = new L.LatLng(d.locationE6.latE6 / 1E6, d.locationE6.lngE6 / 1E6)
|
||||
$.each(edges, function (ind, edge) {
|
||||
//calc distance in m here
|
||||
var distance = 1; //default to 1m, so a low level portal would support it
|
||||
|
||||
//Try to find other portals details
|
||||
var guid = edge.otherPortalGuid
|
||||
if (window.portals[guid] !== undefined) {
|
||||
//get other portals details as o
|
||||
var o = window.portals[guid].options.details;
|
||||
var otherPortalL = new L.LatLng(o.locationE6.latE6 / 1E6, o.locationE6.lngE6 / 1E6);
|
||||
var distance = Math.round(portalL.distanceTo(otherPortalL));
|
||||
}
|
||||
|
||||
if (!(edge.isOrigin)) {
|
||||
distance = distance * -1;
|
||||
}
|
||||
linkParts.push(distance);
|
||||
});
|
||||
var links = linkParts.join(",");
|
||||
|
||||
return resos + "/" + shields + "/" + links; //changed with IPAS 1.1 to / instead of |
|
||||
}
|
||||
|
||||
var setup = function () {
|
||||
window.plugin.ipasLink.setupCallback();
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
21
plugins/broken/make-dummy-deleted-plugin
Executable file
21
plugins/broken/make-dummy-deleted-plugin
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
if test -d ../broken
|
||||
then
|
||||
|
||||
for a in *.js
|
||||
do
|
||||
if test -f ../$a
|
||||
then
|
||||
true
|
||||
# echo $a already exists in ..
|
||||
else
|
||||
echo creating 'deleted' plugin from header of $a
|
||||
|
||||
sed -n -e 's/\@category.*/\@category Deleted/' -e 's/\@description .*/\@description PLUGIN CURRENTLY UNAVAILABLE/' -e 'p' -e '/\/UserScript/q' $a > ../$a
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo error: wrong directory - must be run in plugins/broken
|
||||
fi
|
107
plugins/broken/players-resonators.user.js
Normal file
107
plugins/broken/players-resonators.user.js
Normal file
@ -0,0 +1,107 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-players-resonators@rbino
|
||||
// @name IITC plugin: Player's Resonators
|
||||
// @version 0.1.5.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] The plugins finds the resonators of a given player. The input is in the sidebar.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
/*********************************************************************************************************
|
||||
* Changelog:
|
||||
*
|
||||
* 0.1.5 Added portal and reso counter and reso details (Thanks BJT)
|
||||
* 0.1.4 Added focus link in the toolbox. Some renaming. Removed div to use sidebar style.
|
||||
* 0.1.3 Effective player name (with wrong capitalization) if it finds some reso
|
||||
* 0.1.2 Made nickname case insensitive
|
||||
* 0.1.1 Added mouseover for portal location. Dirty hack to not show mousehover when the alert is fired.
|
||||
* 0.1.0 First public release
|
||||
*********************************************************************************************************/
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.playersResonators = function() {};
|
||||
|
||||
window.plugin.playersResonators.findReso = function(playername) {
|
||||
var s = "";
|
||||
var portalSet = {};
|
||||
var effectiveNick = "";
|
||||
var portalCounter = 0;
|
||||
var resoCounter = 0;
|
||||
// Assuming there can be no agents with same nick with different lower/uppercase
|
||||
var nickToFind = playername.toLowerCase();
|
||||
$.each(window.portals, function(ind, portal){
|
||||
var resoLevels = {};
|
||||
var r = portal.options.details.resonatorArray.resonators;
|
||||
$.each(r, function(ind, reso) {
|
||||
if (!reso) return true;
|
||||
var nick = getPlayerName(reso.ownerGuid);
|
||||
if (nick.toLowerCase() === nickToFind){
|
||||
resoCounter += 1;
|
||||
if (!effectiveNick) {
|
||||
effectiveNick = nick;
|
||||
}
|
||||
if (reso.level in resoLevels){
|
||||
resoLevels[reso.level] += 1;
|
||||
} else {
|
||||
resoLevels[reso.level] = 1;
|
||||
}
|
||||
if (!portalSet.hasOwnProperty(portal.options.guid)){
|
||||
portalSet[portal.options.guid] = true;
|
||||
var latlng = [portal.options.details.locationE6.latE6/1E6, portal.options.details.locationE6.lngE6/1E6].join();
|
||||
var guid = portal.options.guid;
|
||||
var zoomPortal = 'window.zoomToAndShowPortal(\''+guid+'\', ['+latlng+']);return false';
|
||||
var perma = '/intel?latE6='+portal.options.details.locationE6.latE6+'&lngE6='+portal.options.details.locationE6.lngE6+'&z=17&pguid='+guid;
|
||||
var a = $('<a>',{
|
||||
"class": 'help',
|
||||
text: portal.options.details.portalV2.descriptiveText.TITLE,
|
||||
title: portal.options.details.portalV2.descriptiveText.ADDRESS,
|
||||
href: perma,
|
||||
onClick: zoomPortal
|
||||
})[0].outerHTML;
|
||||
portalCounter += 1;
|
||||
s += a + ": ";
|
||||
}
|
||||
}
|
||||
});
|
||||
if (portalSet.hasOwnProperty(portal.options.guid)){
|
||||
for (var i = 8; i>0; i--){
|
||||
if (i in resoLevels)
|
||||
s += resoLevels[i] + "xL" + i + " ";
|
||||
}
|
||||
s += "\n";
|
||||
}
|
||||
});
|
||||
if (s) {
|
||||
// Showing the playername as a "fake" link to avoid the auto-mouseover effect on the first portal
|
||||
fakeLinkPlayer = '<a href="#" onClick="return false;">' + effectiveNick + '</a>'
|
||||
s = fakeLinkPlayer + " has " + resoCounter + " resonators on " + portalCounter + " portals:\n\n" + s;
|
||||
} else {
|
||||
s = playername + " has no resonators in this range\n";
|
||||
}
|
||||
alert(s);
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
var content = '<input id="playerReso" placeholder="Type player name to find resonators..." type="text">';
|
||||
$('#sidebar').append(content);
|
||||
$('#toolbox').append(' <a onclick=$("#playerReso").focus() title="Find all portals with resonators of a certain player">Player\'s Reso</a>');
|
||||
$("#playerReso").keypress(function(e) {
|
||||
if((e.keyCode ? e.keyCode : e.which) !== 13) return;
|
||||
var data = $(this).val();
|
||||
window.plugin.playersResonators.findReso(data);
|
||||
});
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
171
plugins/broken/portal-defense.user.js
Normal file
171
plugins/broken/portal-defense.user.js
Normal file
@ -0,0 +1,171 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-defense@gluckies
|
||||
// @name IITC plugin: portal defense
|
||||
// @category Layer
|
||||
// @version 0.2.2.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows the defense values of every portal (see also "hightlight portals total mitigation" highlighter)
|
||||
// @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==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalDefense = function() {};
|
||||
|
||||
window.plugin.portalDefense.MIN_MAP_ZOOM = 15;
|
||||
window.plugin.portalDefense.DETAIL_MAP_ZOOM = 17;
|
||||
window.plugin.portalDefense.DisplayEnum = {
|
||||
OFF : 0,
|
||||
SIMPLE : 1,
|
||||
DETAIL : 2
|
||||
};
|
||||
|
||||
window.plugin.portalDefense.regionLayers = {};
|
||||
|
||||
// Use portal add and remove event to control render of regions
|
||||
window.plugin.portalDefense.portalAdded = function(data) {
|
||||
data.portal.on('add', function() {
|
||||
plugin.portalDefense.renderAttackRegion(this);
|
||||
});
|
||||
|
||||
data.portal.on('remove', function() {
|
||||
plugin.portalDefense.removeAttackRegion(this);
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.portalDefense.getDisplay = function() {
|
||||
if (map.getZoom() >= window.plugin.portalDefense.DETAIL_MAP_ZOOM) {
|
||||
return window.plugin.portalDefense.DisplayEnum.DETAIL;
|
||||
} else if (map.getZoom() >= window.plugin.portalDefense.MIN_MAP_ZOOM) {
|
||||
return window.plugin.portalDefense.DisplayEnum.SIMPLE;
|
||||
}
|
||||
return window.plugin.portalDefense.DisplayEnum.OFF;
|
||||
}
|
||||
|
||||
window.plugin.portalDefense.renderAttackRegion = function(portal) {
|
||||
plugin.portalDefense.removeAttackRegion(portal);
|
||||
if (window.plugin.portalDefense.currentDisplay == window.plugin.portalDefense.DisplayEnum.OFF) return;
|
||||
|
||||
plugin.portalDefense.regionLayers[portal.options.guid] = [];
|
||||
var defense = window.getPortalMitigationDetails(portal.options.details);
|
||||
if (defense.total) {
|
||||
var display = defense.total;
|
||||
if (window.plugin.portalDefense.currentDisplay == window.plugin.portalDefense.DisplayEnum.DETAIL) {
|
||||
if (defense.shields) {
|
||||
display += "<br>"+"\u2297"+defense.shields;
|
||||
}
|
||||
if(defense.links) {
|
||||
display += "<br>"+"\u21b1"+defense.links;
|
||||
}
|
||||
}
|
||||
var region = L.marker(portal.getLatLng(), {
|
||||
icon: L.divIcon({
|
||||
className: 'plugin-iic-defense',
|
||||
clickable: false,
|
||||
iconAnchor: [-10,10],
|
||||
html: "<div class='defense-label'>"+display+"</div>"
|
||||
}),
|
||||
guid: portal.options.guid
|
||||
});
|
||||
plugin.portalDefense.regionLayers[portal.options.guid].push(region);
|
||||
region.addTo(plugin.portalDefense.regionLayerGroup);
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.portalDefense.reload = function() {
|
||||
$.each(window.portals, function(ind, portal) {
|
||||
// only render mitigation details for portals added to the map
|
||||
if (portal._map) {
|
||||
window.plugin.portalDefense.renderAttackRegion(portal)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.portalDefense.removeAttackRegion = function(portal) {
|
||||
var previousLayers = plugin.portalDefense.regionLayers[portal.options.guid];
|
||||
if (previousLayers) {
|
||||
for (var i = 0; i < previousLayers.length; i++) {
|
||||
plugin.portalDefense.regionLayerGroup.removeLayer(previousLayers[i]);
|
||||
}
|
||||
delete plugin.portalDefense.regionLayers[portal.options.guid];
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.portalDefense.regions = {}
|
||||
|
||||
window.plugin.portalDefense.showOrHide = function() {
|
||||
var ctrl = $('.leaflet-control-layers-selector + span:contains("Portal Defense")').parent();
|
||||
var display = window.plugin.portalDefense.getDisplay();
|
||||
if (display != window.plugin.portalDefense.DisplayEnum.OFF) {
|
||||
// show the layer
|
||||
if(!window.plugin.portalDefense.regionLayerGroup.hasLayer(window.plugin.portalDefense.defenseLayerGroup)) {
|
||||
window.plugin.portalDefense.regionLayerGroup.addLayer(window.plugin.portalDefense.defenseLayerGroup);
|
||||
}
|
||||
ctrl.removeClass('disabled').attr('title', '');
|
||||
} else {
|
||||
// hide the layer
|
||||
if(window.plugin.portalDefense.regionLayerGroup.hasLayer(window.plugin.portalDefense.defenseLayerGroup)) {
|
||||
window.plugin.portalDefense.regionLayerGroup.removeLayer(window.plugin.portalDefense.defenseLayerGroup);
|
||||
}
|
||||
ctrl.addClass('disabled').attr('title', 'Zoom in to show those.');
|
||||
}
|
||||
if (window.plugin.portalDefense.currentDisplay != display) {
|
||||
window.plugin.portalDefense.currentDisplay = display;
|
||||
window.plugin.portalDefense.reload()
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
$('#toolbox').append(' <a onclick="window.plugin.portalDefense.reload()">Reload Defense</a>');
|
||||
$("<style>")
|
||||
.prop("type", "text/css")
|
||||
.html(".plugin-iic-defense {\
|
||||
font-size: 10px;\
|
||||
color: #FFFFBB;\
|
||||
font-family: monospace;\
|
||||
text-align: center;\
|
||||
text-shadow: 0 0 0.5em black, 0 0 0.5em black, 0 0 0.5em black;\
|
||||
pointer-events: none;\
|
||||
-webkit-text-size-adjust:none;\
|
||||
}\
|
||||
.defense-label {\
|
||||
position:relative;\
|
||||
background-color:#1B3E59;\
|
||||
opacity:.6;\
|
||||
border:0.5px solid #FFCE00;\
|
||||
width:22px;\
|
||||
text-align:center;\
|
||||
color:#FFFFFF;\
|
||||
text-align:center;\
|
||||
border-radius:6px;\
|
||||
}")
|
||||
.appendTo("head");
|
||||
|
||||
window.plugin.portalDefense.currentDisplay = window.plugin.portalDefense.getDisplay();
|
||||
map.on('zoomend', window.plugin.portalDefense.showOrHide);
|
||||
|
||||
// this layer is added to the layer chooser, to be toggled on/off
|
||||
window.plugin.portalDefense.regionLayerGroup = new L.LayerGroup();
|
||||
|
||||
// this layer is added into the above layer, and removed from it when we zoom out too far
|
||||
window.plugin.portalDefense.defenseLayerGroup = new L.LayerGroup();
|
||||
|
||||
window.plugin.portalDefense.regionLayerGroup.addLayer(window.plugin.portalDefense.defenseLayerGroup);
|
||||
window.addLayerGroup('Portal Defense', window.plugin.portalDefense.regionLayerGroup, true);
|
||||
|
||||
window.addHook('portalAdded', window.plugin.portalDefense.portalAdded);
|
||||
|
||||
window.plugin.portalDefense.showOrHide();
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
@ -0,0 +1,49 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-bad-deployment-distance@cathesaurus
|
||||
// @name IITC plugin: highlight badly-deployed portals
|
||||
// @category Highlighter
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to show the effective resonator deployment range, where that average is less than 36 metres
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighlighterBadDeploymentDistance = function() {};
|
||||
|
||||
window.plugin.portalHighlighterBadDeploymentDistance.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_deployment = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
var avgDist = window.getAvgResoDist(d);
|
||||
if(avgDist > 0 && avgDist < window.HACK_RANGE*0.9) {
|
||||
portal_deployment = (window.HACK_RANGE - avgDist)/window.HACK_RANGE;
|
||||
}
|
||||
if(portal_deployment > 0) {
|
||||
var fill_opacity = portal_deployment*.85 + .15;
|
||||
// magenta for *exceptionally* close deployments (spoofing? under 1m average), then shades of
|
||||
// red, orange and yellow for further out
|
||||
color = avgDist < 1 ? 'magenta' : avgDist < (window.HACK_RANGE*.25) ? 'red' : avgDist < (window.HACK_RANGE*.6) ? 'orange' : 'yellow';
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Bad Deployment Distance', window.plugin.portalHighlighterBadDeploymentDistance.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
74
plugins/broken/portal-highlighter-can-make-level.user.js
Normal file
74
plugins/broken/portal-highlighter-can-make-level.user.js
Normal file
@ -0,0 +1,74 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-upgrade@vita10gy
|
||||
// @name IITC plugin: highlight portals you can upgrade to a specific level
|
||||
// @category Highlighter
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to highlight portals you can upgrade to a specific level.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel.highlight = function(data,highlight_level) {
|
||||
var d = data.portal.options.details;
|
||||
var current_level = Math.floor(getPortalLevel(d));
|
||||
var potential_level = Math.floor(window.potentialPortalLevel(d));
|
||||
var opacity = .7;
|
||||
if( potential_level > current_level && potential_level === highlight_level) {
|
||||
color = 'red';
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
|
||||
//determines the level of poral a user can make all on their own
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel.playerCanSoloLevel = function(lvl) {
|
||||
var resonators_total = 0;
|
||||
var resonators_placed = 0;
|
||||
var resonator_level = PLAYER.level
|
||||
while(resonators_placed < 8) {
|
||||
for(var i = 0; i<MAX_RESO_PER_PLAYER[resonator_level]; i++) {
|
||||
if(resonators_placed < 8) {
|
||||
resonators_total += resonator_level;
|
||||
resonators_placed++;
|
||||
}
|
||||
}
|
||||
resonator_level--;
|
||||
}
|
||||
return(Math.floor(resonators_total/8));
|
||||
}
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel.getHighlighter = function(lvl) {
|
||||
return(function(data){
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel.highlight(data,lvl);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var setup = function() {
|
||||
// This is the maximum level of a portal a user can be the "last piece of"
|
||||
// yes, even a level 1 can be the difference in bumping a portal up to level 7
|
||||
var max_can_complete = 7;
|
||||
if(PLAYER.level === 8) {
|
||||
max_can_complete = 8;
|
||||
}
|
||||
// The rational behind the "minimum" level below is that showing a level 7 player, for example, all the portals they can make
|
||||
// a level 5 would be silly, as they can make ANY portal a level 5.
|
||||
for(var ptl_lvl = window.plugin.portalHighligherPortalsCanMakeLevel.playerCanSoloLevel()+1; ptl_lvl<=max_can_complete; ptl_lvl++) {
|
||||
window.addPortalHighlighter('Can Make Level ' + ptl_lvl, window.plugin.portalHighligherPortalsCanMakeLevel.getHighlighter(ptl_lvl));
|
||||
}
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
64
plugins/broken/portal-highlighter-imminent-decay.user.js
Normal file
64
plugins/broken/portal-highlighter-imminent-decay.user.js
Normal file
@ -0,0 +1,64 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-imminent-decay@cathesaurus
|
||||
// @name IITC plugin: highlight portals with resonators about to decay
|
||||
// @category Highlighter
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to show resonators due to decay within the next day. Red = portal will decay completely, orange = portal will drop all links, yellow = one or more resonators will decay completely.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighlighterImminentDecay = function() {};
|
||||
|
||||
window.plugin.portalHighlighterImminentDecay.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
if(getTeam(d) !== 0) {
|
||||
//Check the energy of every resonator.
|
||||
var resImminentDecayCount = 0;
|
||||
var resCount = 0;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso !== null) {
|
||||
var level = parseInt(reso.level);
|
||||
var maxResonatorEnergy = window.RESO_NRG[level];
|
||||
var currentResonatorEnergy = parseInt(reso.energyTotal);
|
||||
if((currentResonatorEnergy / maxResonatorEnergy) < 0.15) {
|
||||
resImminentDecayCount++;
|
||||
}
|
||||
resCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if(resImminentDecayCount > 0) {
|
||||
if(resImminentDecayCount === resCount) {
|
||||
var color = 'red';
|
||||
} else if((resCount - resImminentDecayCount) < 3) {
|
||||
color = 'orange';
|
||||
} else {
|
||||
color = 'yellow';
|
||||
}
|
||||
// Apply colour to portal.
|
||||
var params = {fillColor: color, fillOpacity: 1};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
window.COLOR_SELECTED_PORTAL = '#f0f';
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Imminent Decay', window.plugin.portalHighlighterImminentDecay.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
48
plugins/broken/portal-highlighter-mitigation.user.js
Normal file
48
plugins/broken/portal-highlighter-mitigation.user.js
Normal file
@ -0,0 +1,48 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-mitigation@jonatkins
|
||||
// @name IITC plugin: hightlight portals total mitigation
|
||||
// @category Highlighter
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to show mitigation. Shades of red to the maximum of 95, then tints towards purple for over 95
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherMitigation = function() {};
|
||||
|
||||
window.plugin.portalHighligherMitigation.highlight = function(data) {
|
||||
|
||||
var defense = window.getPortalMitigationDetails(data.portal.options.details);
|
||||
|
||||
if (defense.total > 0) {
|
||||
var fill_opacity = (defense.total/95)*.85 + .15;
|
||||
|
||||
var blue = Math.max(0,Math.min(255,Math.round(defense.excess/80*255)));
|
||||
|
||||
var colour = 'rgb(255,0,'+blue+')';
|
||||
|
||||
var params = {fillColor: colour, fillOpacity: fill_opacity};
|
||||
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Mitigation (defense)', window.plugin.portalHighligherMitigation.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
103
plugins/broken/portal-highlighter-mods.user.js
Normal file
103
plugins/broken/portal-highlighter-mods.user.js
Normal file
@ -0,0 +1,103 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-mods@vita10gy
|
||||
// @name IITC plugin: highlight portal mods
|
||||
// @category Highlighter
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote if the portal has the selected mod.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherMods = function() {};
|
||||
|
||||
window.plugin.portalHighligherMods.highlight = function(data, mod_type) {
|
||||
var d = data.portal.options.details;
|
||||
|
||||
if(!jQuery.isArray(mod_type)) {
|
||||
mod_type = [mod_type];
|
||||
}
|
||||
|
||||
var mod_effect = 0;
|
||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
||||
if(mod !== null && jQuery.inArray(mod.type, mod_type) > -1) {
|
||||
switch(mod.rarity){
|
||||
case 'COMMON':
|
||||
mod_effect++;
|
||||
break;
|
||||
case 'RARE':
|
||||
mod_effect+=2;
|
||||
break;
|
||||
case 'VERY_RARE':
|
||||
mod_effect+=3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(mod_effect > 0) {
|
||||
var fill_opacity = mod_effect/12*.8 + .2;
|
||||
var color = 'red';
|
||||
fill_opacity = Math.round(fill_opacity*100)/100;
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherMods.highlightNoMods = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
|
||||
var mods = 0;
|
||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
||||
if(mod !== null) {
|
||||
mods += 1;
|
||||
}
|
||||
});
|
||||
|
||||
if(mods == 0) {
|
||||
var fill_opacity = .6;
|
||||
var color = 'red';
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
} else if(mods <4) {
|
||||
var fill_opacity = .6;
|
||||
var color = 'yellow';
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.plugin.portalHighligherMods.getHighlighter = function(type) {
|
||||
return(function(data){
|
||||
window.plugin.portalHighligherMods.highlight(data,type);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var setup = function() {
|
||||
|
||||
$.each(MOD_TYPE, function(ind, name){
|
||||
window.addPortalHighlighter('Mod: '+name, window.plugin.portalHighligherMods.getHighlighter(ind));
|
||||
});
|
||||
|
||||
window.addPortalHighlighter('Mod: Hackability', window.plugin.portalHighligherMods.getHighlighter(['MULTIHACK', 'HEATSINK']));
|
||||
window.addPortalHighlighter('Mod: Attack', window.plugin.portalHighligherMods.getHighlighter(['FORCE_AMP', 'TURRET']));
|
||||
window.addPortalHighlighter('Mod: Defense', window.plugin.portalHighligherMods.getHighlighter(['RES_SHIELD', 'FORCE_AMP', 'TURRET']));
|
||||
window.addPortalHighlighter('Mod: None', window.plugin.portalHighligherMods.highlightNoMods);
|
||||
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
53
plugins/broken/portal-highlighter-my-8-portals.user.js
Normal file
53
plugins/broken/portal-highlighter-my-8-portals.user.js
Normal file
@ -0,0 +1,53 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-my-8-portals@vita10gy
|
||||
// @name IITC plugin: highlight my level 8's on portals
|
||||
// @category Highlighter
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote portals you have a level 8 on.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherMy8sOnPortals = function() {};
|
||||
|
||||
window.plugin.portalHighligherMy8sOnPortals.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_weakness = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
var color = 'red';
|
||||
var opacity = .7;
|
||||
|
||||
var resCount = false;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso !== null && reso.ownerGuid === PLAYER.guid && reso.level == 8) {
|
||||
resCount = true;
|
||||
}
|
||||
});
|
||||
|
||||
if(resCount) {
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
//Don't list it if it isn't applicable yet
|
||||
if(PLAYER.level == 8) {
|
||||
window.addPortalHighlighter('My Level 8 Resonators', window.plugin.portalHighligherMy8sOnPortals.highlight);
|
||||
}
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
70
plugins/broken/portal-highlighter-my-portals.user.js
Normal file
70
plugins/broken/portal-highlighter-my-portals.user.js
Normal file
@ -0,0 +1,70 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-my-portals@vita10gy
|
||||
// @name IITC plugin: highlight my portals
|
||||
// @category Highlighter
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote portals you have a hand in. Orange is just ownership. Yellow is shields. Red is Resonators. Red trumps both, yellow trumps orange.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherMyPortals = function() {};
|
||||
|
||||
window.plugin.portalHighligherMyPortals.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_weakness = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
var color = '';
|
||||
var opacity = .7;
|
||||
if(PLAYER.guid === d.captured.capturingPlayerId) {
|
||||
color = 'orange';
|
||||
}
|
||||
|
||||
var modCount = 0;
|
||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
||||
if(mod !== null && mod.installingUser === PLAYER.guid) {
|
||||
color = 'yellow';
|
||||
modCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if(modCount > 0) {
|
||||
opacity = modCount*.25*.7 + .3;
|
||||
}
|
||||
|
||||
var resCount = 0;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso !== null && reso.ownerGuid === PLAYER.guid) {
|
||||
color = 'red';
|
||||
resCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if(resCount > 0) {
|
||||
opacity = resCount*.125*.7 + .3;
|
||||
}
|
||||
|
||||
if(color !== '') {
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('My Portals', window.plugin.portalHighligherMyPortals.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
@ -0,0 +1,63 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-outbound-link-counter@cathesaurus
|
||||
// @name IITC plugin: highlight portals running low on outbound links
|
||||
// @category Highlighter
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to show the number of outbound links: red = 8 (i.e. no more outbound links may be made), orange = 6 or 7, yellow = 4 or 5.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighlighterOutboundLinkCounter = function() {};
|
||||
|
||||
window.plugin.portalHighlighterOutboundLinkCounter.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var outgoing = 0;
|
||||
var playerFaction = 0;
|
||||
|
||||
if (window.PLAYER.team === 'RESISTANCE') {
|
||||
playerFaction = window.TEAM_RES;
|
||||
} else {
|
||||
playerFaction = window.TEAM_ENL;
|
||||
}
|
||||
|
||||
// Only interested in portals of player's faction
|
||||
if(getTeam(d) === playerFaction) {
|
||||
if(d.portalV2.linkedEdges) $.each(d.portalV2.linkedEdges, function(ind, link) {
|
||||
if (link.isOrigin) {
|
||||
outgoing++;
|
||||
}
|
||||
});
|
||||
|
||||
if(outgoing > 3) {
|
||||
if(outgoing < 6) {
|
||||
color = 'yellow';
|
||||
} else if(outgoing < 8) {
|
||||
color = 'orange';
|
||||
} else {
|
||||
color = 'red';
|
||||
}
|
||||
var params = {fillColor: color, fillOpacity: 1};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Outbound Links', window.plugin.portalHighlighterOutboundLinkCounter.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
@ -0,0 +1,104 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-by-ap-by-energy-relative@vita10gy
|
||||
// @name IITC plugin: highlight portals by ap/energy (relative)
|
||||
// @category Highlighter
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote AP/Energy value relative to what's currently on the screen. Brighter is better. Orange means your standard 8 down 8 up swap.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP = null;
|
||||
//This is the AP for a run of the mill takedown/putback
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.baseSwapAP = 2350;
|
||||
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var color = 'red';
|
||||
|
||||
if(window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP == null ||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP == null) {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.calculateAPLevels();
|
||||
}
|
||||
var minApE = window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP;
|
||||
var maxApE = window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP;
|
||||
|
||||
if(PLAYER.team !== d.controllingTeam.team) {
|
||||
var ap = getAttackApGain(d);
|
||||
var energy = getCurrentPortalEnergy(d);
|
||||
if(energy < 1) {
|
||||
energy = 1;
|
||||
}
|
||||
portal_ap = ap.enemyAp;
|
||||
|
||||
var opacity = 1;
|
||||
if(minApE !== maxApE) {
|
||||
opacity = ((ap.enemyAp / energy) - minApE) / (maxApE - minApE);
|
||||
}
|
||||
|
||||
if(opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
if(opacity > 1) {
|
||||
opacity = 1;
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.resetAPLevels = function() {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP = null;
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.calculateAPLevels = function() {
|
||||
var displayBounds = map.getBounds();
|
||||
$.each(window.portals, function(qk, portal) {
|
||||
if(displayBounds.contains(portal.getLatLng())) {
|
||||
if(PLAYER.team !== portal.options.details.controllingTeam.team) {
|
||||
var ap = getAttackApGain(portal.options.details);
|
||||
var energy = getCurrentPortalEnergy(portal.options.details);
|
||||
if(energy < 1) {
|
||||
energy = 1;
|
||||
}
|
||||
var portal_ap = ap.enemyAp / energy;
|
||||
if(window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP === null ||
|
||||
portal_ap < window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP) {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP = portal_ap;
|
||||
}
|
||||
if(window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP === null ||
|
||||
portal_ap > window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP) {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP = portal_ap;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('AP/Energy (Relative)', window.plugin.portalHighligherPortalAPPerEnergyRelative.highlight);
|
||||
window.addHook('requestFinished', window.plugin.portalHighligherPortalAPPerEnergyRelative.resetAPLevels);
|
||||
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
99
plugins/broken/portal-highlighter-portal-ap-relative.user.js
Normal file
99
plugins/broken/portal-highlighter-portal-ap-relative.user.js
Normal file
@ -0,0 +1,99 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-by-ap-relative@vita10gy
|
||||
// @name IITC plugin: highlight portals by ap relative
|
||||
// @category Highlighter
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote AP value relative to what's currently on the screen. Brighter is better. Orange means your standard 8 down 8 up swap.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalAPRelative = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalAPRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPRelative.maxAP = null;
|
||||
//This is the AP for a run of the mill takedown/putback
|
||||
window.plugin.portalHighligherPortalAPRelative.baseSwapAP = 2350;
|
||||
|
||||
|
||||
window.plugin.portalHighligherPortalAPRelative.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var color = 'red';
|
||||
|
||||
if(window.plugin.portalHighligherPortalAPRelative.minAP == null ||
|
||||
window.plugin.portalHighligherPortalAPRelative.maxAP == null) {
|
||||
window.plugin.portalHighligherPortalAPRelative.calculateAPLevels();
|
||||
}
|
||||
var minAp = window.plugin.portalHighligherPortalAPRelative.minAP;
|
||||
var maxAp = window.plugin.portalHighligherPortalAPRelative.maxAP;
|
||||
|
||||
var ap = getAttackApGain(d);
|
||||
var portal_ap = ap.friendlyAp;
|
||||
|
||||
if(PLAYER.team !== d.controllingTeam.team) {
|
||||
portal_ap = ap.enemyAp;
|
||||
if(portal_ap === window.plugin.portalHighligherPortalAPRelative.baseSwapAP) {
|
||||
color = 'orange';
|
||||
}
|
||||
}
|
||||
|
||||
var opacity = 1;
|
||||
if(minAp !== maxAp) {
|
||||
opacity = (portal_ap - minAp) / (maxAp - minAp);
|
||||
}
|
||||
|
||||
if(opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
if(opacity > 1) {
|
||||
opacity = 1;
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPRelative.resetAPLevels = function() {
|
||||
window.plugin.portalHighligherPortalAPRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPRelative.maxAP = null;
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPRelative.calculateAPLevels = function() {
|
||||
var displayBounds = map.getBounds();
|
||||
$.each(window.portals, function(qk, portal) {
|
||||
if(displayBounds.contains(portal.getLatLng())) {
|
||||
var ap = getAttackApGain(portal.options.details);
|
||||
var portal_ap = ap.friendlyAp;
|
||||
if(PLAYER.team !== portal.options.details.controllingTeam.team) {
|
||||
portal_ap = ap.enemyAp;
|
||||
}
|
||||
if(window.plugin.portalHighligherPortalAPRelative.minAP === null ||
|
||||
portal_ap < window.plugin.portalHighligherPortalAPRelative.minAP) {
|
||||
window.plugin.portalHighligherPortalAPRelative.minAP = portal_ap;
|
||||
}
|
||||
if(window.plugin.portalHighligherPortalAPRelative.maxAP === null ||
|
||||
portal_ap > window.plugin.portalHighligherPortalAPRelative.maxAP) {
|
||||
window.plugin.portalHighligherPortalAPRelative.maxAP = portal_ap;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('AP (Relative)', window.plugin.portalHighligherPortalAPRelative.highlight);
|
||||
window.addHook('requestFinished', window.plugin.portalHighligherPortalAPRelative.resetAPLevels);
|
||||
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
60
plugins/broken/portal-highlighter-portal-ap.user.js
Normal file
60
plugins/broken/portal-highlighter-portal-ap.user.js
Normal file
@ -0,0 +1,60 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-by-ap@vita10gy
|
||||
// @name IITC plugin: highlight portals by ap
|
||||
// @category Highlighter
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote AP value. Brighter is better. Orange means your standard 8 down 8 up swap.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalAP = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalAP.minAP = 65;
|
||||
//Anything over max AP will be 100% opacity.
|
||||
window.plugin.portalHighligherPortalAP.maxAP = 6000;
|
||||
//This is the AP for a run of the mill takedown/putback
|
||||
window.plugin.portalHighligherPortalAP.baseSwapAP = 2350;
|
||||
|
||||
|
||||
window.plugin.portalHighligherPortalAP.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var color = 'red';
|
||||
var ap = getAttackApGain(d);
|
||||
var portal_ap = ap.friendlyAp;
|
||||
|
||||
if(PLAYER.team !== d.controllingTeam.team) {
|
||||
portal_ap = ap.enemyAp;
|
||||
if(portal_ap === window.plugin.portalHighligherPortalAP.baseSwapAP) {
|
||||
color = 'orange';
|
||||
}
|
||||
}
|
||||
|
||||
var opacity = (portal_ap - window.plugin.portalHighligherPortalAP.minAP) / window.plugin.portalHighligherPortalAP.maxAP;
|
||||
if(opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
if(opacity > 1) {
|
||||
opacity = 1;
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('AP (Static)', window.plugin.portalHighligherPortalAP.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
80
plugins/broken/portal-highlighter-portals-upgrade.user.js
Normal file
80
plugins/broken/portal-highlighter-portals-upgrade.user.js
Normal file
@ -0,0 +1,80 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-upgrade@vita10gy
|
||||
// @name IITC plugin: highlight portals you can upgrade
|
||||
// @category Highlighter
|
||||
// @version 0.2.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Upgradable - Yellow: you can upgrade it at all. Orange: you can change the level. Red: you can make it your level or higher. To Elite: Yellow - To Level 6. Orange - To Level 7. Red - To Level 8.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalsUpgrade = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalsUpgrade.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var current_level = getPortalLevel(d);
|
||||
var potential_level = window.potentialPortalLevel(d);
|
||||
var player_level = PLAYER.level;
|
||||
var opacity = .7;
|
||||
|
||||
if( potential_level > current_level) {
|
||||
potential_level = Math.floor(potential_level);
|
||||
current_level = Math.floor(current_level);
|
||||
//console.log(potential_level + '>' + current_level);
|
||||
var color = 'yellow';
|
||||
if(potential_level > current_level) {
|
||||
color = 'orange';
|
||||
if(potential_level >= player_level) {
|
||||
color = 'red';
|
||||
}
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalsUpgrade.highlight_elite = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var current_level = getPortalLevel(d);
|
||||
var potential_level = window.potentialPortalLevel(d);
|
||||
var opacity = .8;
|
||||
var color = '';
|
||||
potential_level = Math.floor(potential_level);
|
||||
current_level = Math.floor(current_level);
|
||||
|
||||
if( potential_level > current_level && potential_level >= 6) {
|
||||
switch(potential_level) {
|
||||
case 6:
|
||||
color = 'yellow';
|
||||
break;
|
||||
case 7:
|
||||
color = 'orange';
|
||||
break;
|
||||
case 8:
|
||||
color = 'red';
|
||||
opacity = .9;
|
||||
break;
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Upgradable', window.plugin.portalHighligherPortalsUpgrade.highlight);
|
||||
window.addPortalHighlighter('Upgradable to Elite', window.plugin.portalHighligherPortalsUpgrade.highlight_elite);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
@ -0,0 +1,54 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-with-L8-resonators@superd
|
||||
// @name IITC plugin: highlight portals with L8 resonators
|
||||
// @category Highlighter
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill red of the portals, if portal has L8 res
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalsWithL8Resonators = function() {};
|
||||
|
||||
window.plugin.portalsWithL8Resonators.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var has_L8 = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso) {
|
||||
var level = parseInt(reso.level);
|
||||
if(level == 8)
|
||||
{
|
||||
has_L8+=1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(has_L8 > 0)
|
||||
{
|
||||
var color = 'red';
|
||||
var opa = has_L8 * 0.125;
|
||||
var params = {fillColor: color, fillOpacity: opa};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Portals with L8 Resonators', window.plugin.portalsWithL8Resonators.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
453
plugins/broken/portals-list.user.js
Normal file
453
plugins/broken/portals-list.user.js
Normal file
@ -0,0 +1,453 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-portals-list@teo96
|
||||
// @name IITC plugin: show list of portals
|
||||
// @category Info
|
||||
// @version 0.0.18.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Display a sortable list of all visible portals with full details about the team, resonators, shields, etc.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
/* whatsnew
|
||||
* 0.0.15: Add 'age' column to display how long each portal has been controlled by its current owner.
|
||||
* 0.0.14: Add support to new mods (S:Shield - T:Turret - LA:Link Amp - H:Heat-sink - M:Multi-hack - FA:Force Amp)
|
||||
* 0.0.12: Use dialog() instead of alert so the user can drag the box around
|
||||
* 0.0.11: Add nominal energy column and # links, fix sort bug when opened even amounts of times, nits
|
||||
* 0.0.10: Fixed persistent css problem with alert
|
||||
* 0.0.9 : bugs hunt
|
||||
* 0.0.8 : Aborted to avoid problems with Niantic (export portals informations as csv or kml file)
|
||||
* 0.0.7 : more informations available via tooltips (who deployed, energy, ...), new E/AP column
|
||||
* 0.0.6 : Add power charge information into a new column + bugfix
|
||||
* 0.0.5 : Filter portals by clicking on 'All portals', 'Res Portals' or 'Enl Portals'
|
||||
* 0.0.4 : Add link to portals name, one click to display full information in portal panel, double click to zoom on portal, hover to show address
|
||||
* 0.0.3 : sorting ascending/descending and add numbers of portals by faction on top on table
|
||||
* 0.0.2 : add sorting feature when click on header column
|
||||
* 0.0.1 : initial release, show list of portals with level, team, resonators and shield information
|
||||
*
|
||||
* Display code inspired from @vita10gy's scoreboard plugin : iitc-plugin-scoreboard@vita10gy - https://github.com/breunigs/ingress-intel-total-conversion
|
||||
* Portal link code from xelio - iitc: AP List - https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/ap-list.user.js
|
||||
*
|
||||
* todo : export as GPX, Open in Google Maps, more statistics in the header, what else ?
|
||||
*/
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalslist = function() {};
|
||||
|
||||
window.plugin.portalslist.listPortals = []; // structure : name, team, level, resonators = Array, Shields = Array, APgain, Age
|
||||
window.plugin.portalslist.sortOrder=-1;
|
||||
window.plugin.portalslist.enlP = 0;
|
||||
window.plugin.portalslist.resP = 0;
|
||||
window.plugin.portalslist.filter=0;
|
||||
|
||||
//fill the listPortals array with portals avaliable on the map (level filtered portals will not appear in the table)
|
||||
window.plugin.portalslist.getPortals = function() {
|
||||
//filter : 0 = All, 1 = Res, 2 = Enl
|
||||
//console.log('** getPortals');
|
||||
var retval=false;
|
||||
|
||||
var displayBounds = map.getBounds();
|
||||
|
||||
window.plugin.portalslist.listPortals = [];
|
||||
//get portals informations from IITC
|
||||
$.each(window.portals, function(i, portal) {
|
||||
// eliminate offscreen portals (selected, and in padding)
|
||||
if(!displayBounds.contains(portal.getLatLng())) return true;
|
||||
|
||||
retval=true;
|
||||
var d = portal.options.details;
|
||||
var name = d.portalV2.descriptiveText.TITLE;
|
||||
var address = d.portalV2.descriptiveText.ADDRESS;
|
||||
var img = getPortalImageUrl(d);
|
||||
var team = portal.options.team;
|
||||
var now = new Date();
|
||||
var now_ms = now.getTime();// + (now.getTimezoneOffset() * 60000);
|
||||
var age_in_seconds = 0;
|
||||
var age_string_long = 'This portal is not captured.';
|
||||
var age_string_short = 'n/a';
|
||||
if(portal.options.details.hasOwnProperty('captured') && portal.options.details.captured.hasOwnProperty('capturedTime')) {
|
||||
var age_in_seconds = Math.floor((now_ms - portal.options.details.captured.capturedTime)/1000);
|
||||
var age_string_long = window.plugin.portalslist.secondsToString(age_in_seconds, 'l');
|
||||
var age_string_short = window.plugin.portalslist.secondsToString(age_in_seconds, 's');
|
||||
}
|
||||
|
||||
switch (team){
|
||||
case 1 :
|
||||
window.plugin.portalslist.resP++;
|
||||
break;
|
||||
case 2 :
|
||||
window.plugin.portalslist.enlP++;
|
||||
break;
|
||||
}
|
||||
var level = getPortalLevel(d).toFixed(2);
|
||||
var guid = portal.options.guid;
|
||||
|
||||
|
||||
//get resonators informations
|
||||
var resonators = []; // my local resonator array : reso level, reso deployed by, distance to portal, energy total, max
|
||||
var energy = 0;
|
||||
var maxenergy=0;
|
||||
$.each(portal.options.details.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso) {
|
||||
resonators[ind] = [reso.level, window.getPlayerName(reso.ownerGuid), reso.distanceToPortal, reso.energyTotal, RESO_NRG[reso.level]];
|
||||
energy += reso.energyTotal;
|
||||
maxenergy += RESO_NRG[reso.level];
|
||||
} else { resonators[ind] = [0,'',0,0,0]; }
|
||||
});
|
||||
// Sort resonators array by resonator level
|
||||
resonators.sort(function (a, b) {return b[0] - a[0]});
|
||||
|
||||
//get mods informations
|
||||
var mods = [];
|
||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
||||
var modShortName='';
|
||||
if (mod) {
|
||||
switch (mod.displayName) {
|
||||
case 'Portal Shield':
|
||||
modShortName = 'S';
|
||||
break;
|
||||
case 'Force Amp':
|
||||
modShortName = 'FA';
|
||||
break;
|
||||
case 'Link Amp':
|
||||
modShortName = 'LA';
|
||||
break;
|
||||
case 'Heat Sink':
|
||||
modShortName = 'H';
|
||||
break;
|
||||
case 'Multi-hack':
|
||||
modShortName = 'M';
|
||||
break;
|
||||
case 'Turret':
|
||||
modShortName = 'T';
|
||||
break;
|
||||
default:
|
||||
modShortName = '';
|
||||
break;
|
||||
}
|
||||
if (modShortName === '') {
|
||||
mods[ind] = ['', '', ''];
|
||||
} else {
|
||||
if ((modShortName === 'S') &&
|
||||
((mod.rarity=='COMMON' && mod.stats.MITIGATION == 6) ||
|
||||
(mod.rarity=='RARE' && mod.stats.MITIGATION == 8) ||
|
||||
(mod.rarity=='VERY_RARE' && mod.stats.MITIGATION == 10)))
|
||||
modShortName=modShortName+'!';
|
||||
mods[ind] = [mod.rarity, getPlayerName(mod.installingUser), modShortName, mod.displayName];
|
||||
}
|
||||
}else { mods[ind] = ['', '', '']; }
|
||||
});
|
||||
|
||||
var APgain= getAttackApGain(d).enemyAp;
|
||||
var thisPortal = {'portal': d,
|
||||
'name': name,
|
||||
'team': team,
|
||||
'level': level,
|
||||
'guid': guid,
|
||||
'resonators': resonators,
|
||||
'energyratio': maxenergy ? Math.floor(energy/maxenergy*100) : 0,
|
||||
'mods': mods,
|
||||
'APgain': APgain,
|
||||
'EAP': (energy/APgain).toFixed(2),
|
||||
'energy': energy,
|
||||
'maxenergy': maxenergy,
|
||||
'links': d.portalV2.linkedEdges.length,
|
||||
'lat': portal._latlng.lat,
|
||||
'lng': portal._latlng.lng,
|
||||
'address': address,
|
||||
'img': img,
|
||||
'age': age_in_seconds,
|
||||
'age_string_long': age_string_long,
|
||||
'age_string_short': age_string_short};
|
||||
window.plugin.portalslist.listPortals.push(thisPortal);
|
||||
});
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
window.plugin.portalslist.displayPL = function() {
|
||||
// debug tools
|
||||
//var start = new Date().getTime();
|
||||
//console.log('***** Start ' + start);
|
||||
|
||||
var html = '';
|
||||
window.plugin.portalslist.sortOrder=-1;
|
||||
window.plugin.portalslist.enlP = 0;
|
||||
window.plugin.portalslist.resP = 0;
|
||||
|
||||
if (window.plugin.portalslist.getPortals()) {
|
||||
html += window.plugin.portalslist.portalTable('level', window.plugin.portalslist.sortOrder,window.plugin.portalslist.filter);
|
||||
} else {
|
||||
html = '<table><tr><td>Nothing to show!</td></tr></table>';
|
||||
};
|
||||
|
||||
dialog({
|
||||
html: '<div id="portalslist">' + html + '</div>',
|
||||
dialogClass: 'ui-dialog-portalslist',
|
||||
title: 'Portal list: ' + window.plugin.portalslist.listPortals.length + ' ' + (window.plugin.portalslist.listPortals.length == 1 ? 'portal' : 'portals'),
|
||||
id: 'portal-list',
|
||||
width: 800
|
||||
});
|
||||
|
||||
//run the name resolving process
|
||||
resolvePlayerNames();
|
||||
|
||||
//debug tools
|
||||
//end = new Date().getTime();
|
||||
//console.log('***** end : ' + end + ' and Elapse : ' + (end - start));
|
||||
}
|
||||
|
||||
window.plugin.portalslist.portalTable = function(sortBy, sortOrder, filter) {
|
||||
// sortOrder <0 ==> desc, >0 ==> asc, i use sortOrder * -1 to change the state
|
||||
window.plugin.portalslist.filter=filter;
|
||||
var portals=window.plugin.portalslist.listPortals;
|
||||
|
||||
//Array sort
|
||||
window.plugin.portalslist.listPortals.sort(function(a, b) {
|
||||
var retVal = 0;
|
||||
switch (sortBy) {
|
||||
case 'names':
|
||||
retVal = a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
|
||||
break;
|
||||
case 'r1':
|
||||
retVal = b.resonators[0][0] - a.resonators[0][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r2':
|
||||
retVal = b.resonators[1][0] - a.resonators[1][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r3':
|
||||
retVal = b.resonators[2][0] - a.resonators[2][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r4':
|
||||
retVal = b.resonators[3][0] - a.resonators[3][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r5':
|
||||
retVal = b.resonators[4][0] - a.resonators[4][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r6':
|
||||
retVal = b.resonators[5][0] - a.resonators[5][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r7':
|
||||
retVal = b.resonators[6][0] - a.resonators[6][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r8':
|
||||
retVal = b.resonators[7][0] - a.resonators[7][0];
|
||||
break;
|
||||
case 's1':
|
||||
retVal = a.mods[0][2] > b.mods[0][2] ? -1 : 1;
|
||||
break;
|
||||
case 's2':
|
||||
retVal = a.mods[1][2] > b.mods[1][2] ? -1 : 1;
|
||||
break;
|
||||
case 's3':
|
||||
retVal = a.mods[2][2] > b.mods[2][2] ? -1 : 1;
|
||||
break;
|
||||
case 's4':
|
||||
retVal = a.mods[3][2] > b.mods[3][2] ? -1 : 1;
|
||||
break;
|
||||
default:
|
||||
retVal = b[sortBy] - a[sortBy];
|
||||
break;
|
||||
}
|
||||
if (sortOrder > 0) retVal = -retVal; //thx @jonatkins
|
||||
return retVal;
|
||||
});
|
||||
|
||||
var sort = window.plugin.portalslist.portalTableSort;
|
||||
var html = window.plugin.portalslist.stats();
|
||||
html += '<table>'
|
||||
+ '<tr><th ' + sort('names', sortBy, -1) + '>Portal</th>'
|
||||
+ '<th ' + sort('level', sortBy, -1) + '>Level</th>'
|
||||
+ '<th title="Team" ' + sort('team', sortBy, -1) + '>T</th>'
|
||||
+ '<th ' + sort('r1', sortBy, -1) + '>R1</th>'
|
||||
+ '<th ' + sort('r2', sortBy, -1) + '>R2</th>'
|
||||
+ '<th ' + sort('r3', sortBy, -1) + '>R3</th>'
|
||||
+ '<th ' + sort('r4', sortBy, -1) + '>R4</th>'
|
||||
+ '<th ' + sort('r5', sortBy, -1) + '>R5</th>'
|
||||
+ '<th ' + sort('r6', sortBy, -1) + '>R6</th>'
|
||||
+ '<th ' + sort('r7', sortBy, -1) + '>R7</th>'
|
||||
+ '<th ' + sort('r8', sortBy, -1) + '>R8</th>'
|
||||
+ '<th ' + sort('energy', sortBy, -1) + '>Energy</th>'
|
||||
+ '<th ' + sort('energyratio', sortBy, -1) + '>%</th>'
|
||||
+ '<th ' + sort('links', sortBy, -1) + '>Links</th>'
|
||||
+ '<th ' + sort('s1', sortBy, -1) + '>M1</th>'
|
||||
+ '<th ' + sort('s2', sortBy, -1) + '>M2</th>'
|
||||
+ '<th ' + sort('s3', sortBy, -1) + '>M3</th>'
|
||||
+ '<th ' + sort('s4', sortBy, -1) + '>M4</th>'
|
||||
+ '<th ' + sort('mitigation', sortBy, -1) + '>Mit.</th>'
|
||||
+ '<th ' + sort('APgain', sortBy, -1) + '>AP Gain</th>'
|
||||
+ '<th title="Energy / AP Gain ratio" ' + sort('EAP', sortBy, -1) + '>E/AP</th>'
|
||||
+ '<th ' + sort('age', sortBy, -1) + '>Age</th></tr>';
|
||||
|
||||
|
||||
$.each(portals, function(ind, portal) {
|
||||
|
||||
if (filter === 0 || filter === portal.team) {
|
||||
html += '<tr class="' + (portal.team === 1 ? 'res' : (portal.team === 2 ? 'enl' : 'neutral')) + '">'
|
||||
+ '<td style="">' + window.plugin.portalslist.getPortalLink(portal.portal, portal.guid) + '</td>'
|
||||
+ '<td class="L' + Math.floor(portal.level) +'">' + portal.level + '</td>'
|
||||
+ '<td style="text-align:center;">' + portal.team + '</td>';
|
||||
|
||||
var mitigationDetails = getPortalMitigationDetails(portal.portal);
|
||||
portal.mitigation = mitigationDetails.total + mitigationDetails.excess;
|
||||
|
||||
var title;
|
||||
var percent;
|
||||
$.each([0, 1, 2, 3 ,4 ,5 ,6 ,7], function(ind, slot) {
|
||||
percent = portal.resonators[slot][4] ? Math.floor(portal.resonators[slot][3]/portal.resonators[slot][4]*100) : 0;
|
||||
title = 'title="owner: <b>' + portal.resonators[slot][1] + '</b><br>'
|
||||
+ 'energy: ' + portal.resonators[slot][3] + ' / ' + portal.resonators[slot][4] + ' (' + percent + '%)<br>'
|
||||
+ 'distance: ' + portal.resonators[slot][2] + 'm';
|
||||
|
||||
html += '<td class="L' + portal.resonators[slot][0] +'" ' + title + '">' + portal.resonators[slot][0] + '</td>';
|
||||
|
||||
});
|
||||
|
||||
html += '<td style="cursor:help" title="'+ portal.energy +'">' + prettyEnergy(portal.energy) + '</td>'
|
||||
+ '<td style="cursor:help" title="' + portal.energy + ' / ' + portal.maxenergy +'">' + portal.energyratio + '%</td>'
|
||||
+ '<td style="cursor:help" title="' + portal.links + '">' + portal.links + '</td>'
|
||||
+ '<td style="cursor:help; background-color: '+COLORS_MOD[portal.mods[0][0]]+';" title="Mod : ' + portal.mods[0][3] + '\nInstalled by : ' + portal.mods[0][1] + '\nRarity : ' + portal.mods[0][0] + '">' + portal.mods[0][2] + '</td>'
|
||||
+ '<td style="cursor:help; background-color: '+COLORS_MOD[portal.mods[1][0]]+';" title="Mod : ' + portal.mods[1][3] + '\nInstalled by : ' + portal.mods[1][1] + '\nRarity : ' + portal.mods[1][0] + '">' + portal.mods[1][2] + '</td>'
|
||||
+ '<td style="cursor:help; background-color: '+COLORS_MOD[portal.mods[2][0]]+';" title="Mod : ' + portal.mods[2][3] + '\nInstalled by : ' + portal.mods[2][1] + '\nRarity : ' + portal.mods[2][0] + '">' + portal.mods[2][2] + '</td>'
|
||||
+ '<td style="cursor:help; background-color: '+COLORS_MOD[portal.mods[3][0]]+';" title="Mod : ' + portal.mods[3][3] + '\nInstalled by : ' + portal.mods[3][1] + '\nRarity : ' + portal.mods[3][0] + '">' + portal.mods[3][2] + '</td>'
|
||||
+ '<td>' + portal.mitigation + '</td>'
|
||||
+ '<td>' + portal.APgain + '</td>'
|
||||
+ '<td>' + portal.EAP + '</td>'
|
||||
+ '<td style="cursor:help;" title="' + portal.age_string_long + '">' + portal.age_string_short + '</td>';
|
||||
|
||||
html+= '</tr>';
|
||||
}
|
||||
});
|
||||
html += '</table>';
|
||||
|
||||
html += '<div class="disclaimer">Click on portals table headers to sort by that column. '
|
||||
+ 'Click on <b>All Portals, Resistance Portals, Enlightened Portals</b> to filter<br>'
|
||||
+ 'Thanks to @vita10gy & @xelio for their IITC plugins who inspired me. A <a href="https://plus.google.com/113965246471577467739">@teo96</a> production. Vive la Résistance !</div>';
|
||||
|
||||
window.plugin.portalslist.sortOrder = window.plugin.portalslist.sortOrder*-1;
|
||||
return html;
|
||||
}
|
||||
|
||||
window.plugin.portalslist.stats = function(sortBy) {
|
||||
//console.log('** stats');
|
||||
var html = '<table><tr>'
|
||||
+ '<td class="filterAll" style="cursor:pointer" onclick="window.plugin.portalslist.portalTable(\'level\',-1,0)"><a href=""></a>All Portals : (click to filter)</td><td class="filterAll">' + window.plugin.portalslist.listPortals.length + '</td>'
|
||||
+ '<td class="filterRes" style="cursor:pointer" class="sorted" onclick="window.plugin.portalslist.portalTable(\'level\',-1,1)">Resistance Portals : </td><td class="filterRes">' + window.plugin.portalslist.resP +' (' + Math.floor(window.plugin.portalslist.resP/window.plugin.portalslist.listPortals.length*100) + '%)</td>'
|
||||
+ '<td class="filterEnl" style="cursor:pointer" class="sorted" onclick="window.plugin.portalslist.portalTable(\'level\',-1,2)">Enlightened Portals : </td><td class="filterEnl">'+ window.plugin.portalslist.enlP +' (' + Math.floor(window.plugin.portalslist.enlP/window.plugin.portalslist.listPortals.length*100) + '%)</td>'
|
||||
+ '</tr>'
|
||||
+ '</table>';
|
||||
return html;
|
||||
}
|
||||
|
||||
// A little helper function so the above isn't so messy
|
||||
window.plugin.portalslist.portalTableSort = function(name, by) {
|
||||
var retVal = 'data-sort="' + name + '"';
|
||||
if(name === by) {
|
||||
retVal += ' class="sorted"';
|
||||
}
|
||||
return retVal;
|
||||
};
|
||||
|
||||
// portal link - single click: select portal
|
||||
// double click: zoom to and select portal
|
||||
// hover: show address
|
||||
// code from getPortalLink function by xelio from iitc: AP List - https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/ap-list.user.js
|
||||
window.plugin.portalslist.getPortalLink = function(portal,guid) {
|
||||
|
||||
var latlng = [portal.locationE6.latE6/1E6, portal.locationE6.lngE6/1E6].join();
|
||||
var jsSingleClick = 'window.renderPortalDetails(\''+guid+'\');return false';
|
||||
var jsDoubleClick = 'window.zoomToAndShowPortal(\''+guid+'\', ['+latlng+']);return false';
|
||||
var perma = '/intel?latE6='+portal.locationE6.latE6+'&lngE6='+portal.locationE6.lngE6+'&z=17&pguid='+guid;
|
||||
|
||||
//Use Jquery to create the link, which escape characters in TITLE and ADDRESS of portal
|
||||
var a = $('<a>',{
|
||||
"class": 'help',
|
||||
text: portal.portalV2.descriptiveText.TITLE,
|
||||
title: portal.portalV2.descriptiveText.ADDRESS,
|
||||
href: perma,
|
||||
onClick: jsSingleClick,
|
||||
onDblClick: jsDoubleClick
|
||||
})[0].outerHTML;
|
||||
var div = '<div class="portalTitle">'+a+'</div>';
|
||||
return div;
|
||||
}
|
||||
|
||||
// length can be "s" or "l" for "short" or "long"
|
||||
window.plugin.portalslist.secondsToString = function(seconds, length) {
|
||||
var numdays = Math.floor(seconds / 86400);
|
||||
var numhours = Math.floor((seconds % 86400) / 3600);
|
||||
var numminutes = Math.floor(((seconds % 86400) % 3600) / 60);
|
||||
var numseconds = ((seconds % 86400) % 3600) % 60;
|
||||
if(length === "l") {
|
||||
return numdays + " days " + numhours + " hours " + numminutes + " minutes " + numseconds + " seconds";
|
||||
} else {
|
||||
return numdays + "d" + numhours + "h";
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
$('#toolbox').append(' <a onclick="window.plugin.portalslist.displayPL()" title="Display a list of portals in the current view">Portals list</a>');
|
||||
$('head').append('<style>' +
|
||||
//style.css sets dialog max-width to 700px - override that here
|
||||
// (the width: 800 parameter to dialog is NOT enough to override that css limit)
|
||||
'#dialog-portal-list {max-width: 800px !important;}' +
|
||||
'#portalslist table {margin-top:5px; border-collapse: collapse; empty-cells: show; width:100%; clear: both;}' +
|
||||
'#portalslist table td, #portalslist table th {border-bottom: 1px solid #0b314e; padding:3px; color:white; background-color:#1b415e}' +
|
||||
'#portalslist table tr.res td { background-color: #005684; }' +
|
||||
'#portalslist table tr.enl td { background-color: #017f01; }' +
|
||||
'#portalslist table tr.neutral td { background-color: #000000; }' +
|
||||
'#portalslist table th { text-align: center;}' +
|
||||
'#portalslist table td { text-align: center;}' +
|
||||
'#portalslist table td.L0 { cursor: help; background-color: #000000 !important;}' +
|
||||
'#portalslist table td.L1 { cursor: help; background-color: #FECE5A !important;}' +
|
||||
'#portalslist table td.L2 { cursor: help; background-color: #FFA630 !important;}' +
|
||||
'#portalslist table td.L3 { cursor: help; background-color: #FF7315 !important;}' +
|
||||
'#portalslist table td.L4 { cursor: help; background-color: #E40000 !important;}' +
|
||||
'#portalslist table td.L5 { cursor: help; background-color: #FD2992 !important;}' +
|
||||
'#portalslist table td.L6 { cursor: help; background-color: #EB26CD !important;}' +
|
||||
'#portalslist table td.L7 { cursor: help; background-color: #C124E0 !important;}' +
|
||||
'#portalslist table td.L8 { cursor: help; background-color: #9627F4 !important;}' +
|
||||
'#portalslist table td:nth-child(1) { text-align: left;}' +
|
||||
'#portalslist table th { cursor:pointer; text-align: right;}' +
|
||||
'#portalslist table th:nth-child(1) { text-align: left;}' +
|
||||
'#portalslist table th.sorted { color:#FFCE00; }' +
|
||||
'#portalslist .filterAll { margin-top: 10px;}' +
|
||||
'#portalslist .filterRes { margin-top: 10px; background-color: #005684 }' +
|
||||
'#portalslist .filterEnl { margin-top: 10px; background-color: #017f01 }' +
|
||||
'#portalslist .disclaimer { margin-top: 10px; font-size:10px; }' +
|
||||
'#portalslist .portalTitle { display: inline-block; width: 160px !important; min-width: 160px !important; max-width: 160px !important; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }' +
|
||||
'</style>');
|
||||
// Setup sorting
|
||||
$(document).on('click.portalslist', '#portalslist table th', function() {
|
||||
$('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,window.plugin.portalslist.filter));
|
||||
});
|
||||
$(document).on('click.portalslist', '#portalslist .filterAll', function() {
|
||||
$('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,0));
|
||||
});
|
||||
$(document).on('click.portalslist', '#portalslist .filterRes', function() {
|
||||
$('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,1));
|
||||
});
|
||||
$(document).on('click.portalslist', '#portalslist .filterEnl', function() {
|
||||
$('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,2));
|
||||
});
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
340
plugins/broken/scoreboard.user.js
Normal file
340
plugins/broken/scoreboard.user.js
Normal file
@ -0,0 +1,340 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-scoreboard@vita10gy
|
||||
// @name IITC plugin: show a localized scoreboard.
|
||||
// @category Info
|
||||
// @version 0.1.9.@@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*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// 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]['count_mods'] = 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_mods'] = 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);
|
||||
|
||||
// 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]['count_fields']++;
|
||||
scores['team'][team]['field_area'] += fieldArea;
|
||||
val.options.data.fieldArea = fieldArea;
|
||||
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);
|
||||
|
||||
scores['team'][team]['count_links']++;
|
||||
|
||||
var linkLength = window.plugin.scoreboard.portalDistance(link.options.data.edge.destinationPortalLocation,link.options.data.edge.originPortalLocation);
|
||||
scores['team'][team]['link_length'] += linkLength;
|
||||
|
||||
var largestLink = scores['team'][team]['largest']['link'];
|
||||
if(largestLink === undefined || largestLink.distance < linkLength) {
|
||||
largestLink = {};
|
||||
largestLink.distance = linkLength;
|
||||
}
|
||||
scores['team'][team]['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) {
|
||||
window.plugin.scoreboard.initPlayer(mod.installingUser, team);
|
||||
somethingInView = true;
|
||||
scores['team'][team]['count_mods']++;
|
||||
scores['player'][mod.installingUser]['count_mods']++;
|
||||
}
|
||||
});
|
||||
|
||||
$.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.teamTableRow = function(field,title) {
|
||||
var scores = window.plugin.scoreboard.scores['team'];
|
||||
var retVal = '<tr><td>'
|
||||
+ title
|
||||
+ '</td><td class="number">'
|
||||
+ window.digits(Math.round(scores[TEAM_RES][field]))
|
||||
+ '</td><td class="number">'
|
||||
+ window.digits(Math.round(scores[TEAM_ENL][field]))
|
||||
+ '</td><td class="number">'
|
||||
+ window.digits(Math.round(scores[TEAM_RES][field] + scores[TEAM_ENL][field]))
|
||||
+ '</td></tr>';
|
||||
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 = '<div title="' + title + '">'
|
||||
+ window.digits(Math.round(field.options.data.fieldArea))
|
||||
+ '</div>';
|
||||
|
||||
} else {
|
||||
retVal = 'N/A';
|
||||
}
|
||||
return retVal;
|
||||
};
|
||||
|
||||
window.plugin.scoreboard.playerTableRow = function(playerGuid) {
|
||||
var scores = window.plugin.scoreboard.scores['player'];
|
||||
var retVal = '<tr class="'
|
||||
+ (scores[playerGuid]['team'] === TEAM_RES ? 'res' : 'enl')
|
||||
+'"><td>'
|
||||
+ window.getPlayerName(playerGuid);
|
||||
+ '</td>';
|
||||
|
||||
$.each(['count_portals','count_resonators','count_mods'], function(i, field) {
|
||||
retVal += '<td class="number">'
|
||||
+ window.digits(Math.round(scores[playerGuid][field]))
|
||||
+ '</td>';
|
||||
});
|
||||
retVal += '</tr>';
|
||||
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 = '<table>'
|
||||
+ '<tr><th ' + sort('names', sortBy) + '>Player</th>'
|
||||
+ '<th ' + sort('count_portals', sortBy) + '>Portals</th>'
|
||||
+ '<th ' + sort('count_resonators', sortBy) + '>Resonators</th>'
|
||||
+ '<th ' + sort('count_mods', sortBy) + '>Mods</th></tr>';
|
||||
$.each(window.plugin.scoreboard.playerGuids, function(index, guid) {
|
||||
scoreHtml += window.plugin.scoreboard.playerTableRow(guid);
|
||||
});
|
||||
scoreHtml += '</table>';
|
||||
|
||||
return scoreHtml;
|
||||
}
|
||||
|
||||
// A little helper function 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 scoreHtml = '';
|
||||
var title = '';
|
||||
|
||||
if(somethingInView) {
|
||||
scoreHtml += '<table>'
|
||||
+ '<tr><th></th><th class="number">Resistance</th><th class="number">Enlightened</th><th class="number">Total</th></tr>'
|
||||
+ 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')
|
||||
+ window.plugin.scoreboard.teamTableRow('count_mods','Mods')
|
||||
+ '</table>';
|
||||
|
||||
scoreHtml += '<table>'
|
||||
+ '<tr><th></th><th>Resistance</th><th>Enlightened</th></tr>'
|
||||
+ '<tr><td>Largest Field (km²)</td><td>'
|
||||
+ window.plugin.scoreboard.fieldInfoArea(scores['team'][TEAM_RES]['largest']['field_area'])
|
||||
+ '</td><td>'
|
||||
+ window.plugin.scoreboard.fieldInfoArea(scores['team'][TEAM_ENL]['largest']['field_area'])
|
||||
+ '</td></tr>'
|
||||
+ '<tr><td>Longest Link (m)</td><td>';
|
||||
if(scores['team'][TEAM_RES]['largest']['link'] === undefined) {
|
||||
scoreHtml += 'N/A';
|
||||
}
|
||||
else {
|
||||
scoreHtml += window.digits(Math.round(scores['team'][TEAM_RES]['largest']['link']['distance']));
|
||||
}
|
||||
scoreHtml += '</td><td>';
|
||||
|
||||
if(scores['team'][TEAM_ENL]['largest']['link'] === undefined) {
|
||||
scoreHtml += 'N/A';
|
||||
}
|
||||
else {
|
||||
scoreHtml += window.digits(Math.round(scores['team'][TEAM_ENL]['largest']['link']['distance']));
|
||||
}
|
||||
scoreHtml += '</td></tr>'
|
||||
+ '</table>'
|
||||
+ '<div id="players">'
|
||||
+ window.plugin.scoreboard.playerTable('count_portals')
|
||||
+ '</div>';
|
||||
|
||||
scoreHtml += '<div class="disclaimer">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.</div>';
|
||||
} else {
|
||||
scoreHtml += 'You need something in view.';
|
||||
title = 'nothing in view';
|
||||
}
|
||||
|
||||
dialog({
|
||||
html: '<div id="scoreboard">' + scoreHtml + '</div>',
|
||||
title: 'Scoreboard: ' + title,
|
||||
dialogClass: 'ui-dialog-scoreboard',
|
||||
id: 'scoreboard'
|
||||
});
|
||||
|
||||
//run the name resolving process
|
||||
resolvePlayerNames();
|
||||
}
|
||||
|
||||
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(' <a onclick="window.plugin.scoreboard.display()" title="Display a scoreboard per team for the current view">Scoreboard</a>');
|
||||
$('head').append('<style>' +
|
||||
'.ui-dialog-scoreboard {width: auto !important; min-width: 400px !important; max-width: 600px !important;}' +
|
||||
'#scoreboard table {margin-top:10px; border-collapse: collapse; empty-cells: show; width:100%; clear: both;}' +
|
||||
'#scoreboard table td, #scoreboard table th {border-bottom: 1px solid #0b314e; padding:3px; color:white; background-color:#1b415e}' +
|
||||
'#scoreboard table tr.res td { background-color: #005684; }' +
|
||||
'#scoreboard table tr.enl td { background-color: #017f01; }' +
|
||||
'#scoreboard table tr:nth-child(even) td { opacity: .8 }' +
|
||||
'#scoreboard table tr:nth-child(odd) td { color: #ddd !important; }' +
|
||||
'#scoreboard table th { text-align:left }' +
|
||||
'#scoreboard table td.number, #scoreboard table th.number { text-align:right }' +
|
||||
'#players table th { cursor:pointer; text-align: right;}' +
|
||||
'#players table th:nth-child(1) { text-align: left;}' +
|
||||
'#scoreboard table th.sorted { color:#FFCE00; }' +
|
||||
'#scoreboard .disclaimer { margin-top:10px; font-size:10px; }' +
|
||||
'.mu_score { margin-bottom: 10px; }' +
|
||||
'.mu_score span { overflow: hidden; padding-top:2px; padding-bottom: 2px; display: block; font-weight: bold; float: left; box-sizing: border-box; -moz-box-sizing:border-box; -webkit-box-sizing:border-box; }' +
|
||||
'.mu_score span.res { background-color: #005684; text-align: right; padding-right:4px; }' +
|
||||
'.mu_score span.enl { background-color: #017f01; padding-left: 4px; }' +
|
||||
'</style>');
|
||||
// Setup sorting
|
||||
$(document).on('click', '#players table th', function() {
|
||||
$('#players').html(window.plugin.scoreboard.playerTable($(this).data('sort')));
|
||||
});
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
@ -1,141 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-compute-ap-stats@Hollow011
|
||||
// @name IITC plugin: Compute AP statistics
|
||||
// @category Info
|
||||
// @category Deleted
|
||||
// @version 0.3.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Displays the per-team AP gains available in the current view.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.compAPStats = function() {};
|
||||
|
||||
window.plugin.compAPStats.setupCallback = function() {
|
||||
// add a new div to the bottom of the sidebar and style it
|
||||
$('#sidebar').append('<div id="available_ap_display"></div>');
|
||||
$('#available_ap_display').css({'color':'#ffce00', 'font-size':'90%', 'padding':'4px 2px'});
|
||||
|
||||
// do an initial calc for sidebar sizing purposes
|
||||
window.plugin.compAPStats.onPositionMove();
|
||||
|
||||
// make the value update when the map data updates
|
||||
window.addHook('mapDataRefreshEnd', window.plugin.compAPStats.onPositionMove);
|
||||
|
||||
}
|
||||
|
||||
window.plugin.compAPStats.onPositionMove = function() {
|
||||
var result = window.plugin.compAPStats.compAPStats();
|
||||
$('#available_ap_display').html('Available AP in this area:<table>'
|
||||
+ '<tr><td>Enlightened:</td><td style="text-align:right">' + digits(result[1]) + '</td></tr>'
|
||||
+ '<tr><td>Resistance:</td><td style="text-align:right">' + digits(result[0]) + '</td></tr>'
|
||||
+ '</table>');
|
||||
}
|
||||
|
||||
window.plugin.compAPStats.missingResonatorAP = function(portal) {
|
||||
var resAP = 0;
|
||||
var missing_resonators = 0;
|
||||
$.each(portal.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso === null) {
|
||||
missing_resonators++;
|
||||
}
|
||||
});
|
||||
if(missing_resonators > 0) {
|
||||
resAP = window.DEPLOY_RESONATOR * missing_resonators;
|
||||
resAP += window.COMPLETION_BONUS;
|
||||
}
|
||||
return(resAP);
|
||||
};
|
||||
|
||||
window.plugin.compAPStats.compAPStats = function() {
|
||||
|
||||
var totalAP_RES = 0;
|
||||
var totalAP_ENL = 0;
|
||||
|
||||
var allResEdges = [];
|
||||
var allResFields = [];
|
||||
var allEnlEdges = [];
|
||||
var allEnlFields = [];
|
||||
|
||||
var displayBounds = map.getBounds();
|
||||
|
||||
// Grab every portal in the viewable area and compute individual AP stats
|
||||
$.each(window.portals, function(ind, portal) {
|
||||
var d = portal.options.details;
|
||||
|
||||
// eliminate offscreen portals (selected, and in padding)
|
||||
if(!displayBounds.contains(portal.getLatLng())) return true;
|
||||
|
||||
var portalStats = getAttackApGain(d);
|
||||
var portalSum = portalStats.resoAp + portalStats.captureAp;
|
||||
|
||||
if (getTeam(d) === TEAM_ENL) {
|
||||
totalAP_RES += portalSum;
|
||||
|
||||
$.each(d.portalV2.linkedEdges||[], function(ind, edge) {
|
||||
if(!edge) return true;
|
||||
allEnlEdges.push(edge.edgeGuid);
|
||||
});
|
||||
|
||||
$.each(d.portalV2.linkedFields||[], function(ind, field) {
|
||||
if(!field) return true;
|
||||
allEnlFields.push(field);
|
||||
});
|
||||
|
||||
totalAP_ENL += window.plugin.compAPStats.missingResonatorAP(d);
|
||||
|
||||
}
|
||||
else if (getTeam(d) === TEAM_RES) {
|
||||
totalAP_ENL += portalSum;
|
||||
|
||||
$.each(d.portalV2.linkedEdges||[], function(ind, edge) {
|
||||
if(!edge) return true;
|
||||
allResEdges.push(edge.edgeGuid);
|
||||
});
|
||||
|
||||
$.each(d.portalV2.linkedFields||[], function(ind, field) {
|
||||
if(!field) return true;
|
||||
allResFields.push(field);
|
||||
});
|
||||
|
||||
totalAP_RES += window.plugin.compAPStats.missingResonatorAP(d);
|
||||
|
||||
} else {
|
||||
// it's a neutral portal, potential for both teams. by definition no fields or edges
|
||||
totalAP_ENL += portalSum;
|
||||
totalAP_RES += portalSum;
|
||||
}
|
||||
});
|
||||
|
||||
// Compute team field AP
|
||||
allResFields = uniqueArray(allResFields);
|
||||
totalAP_ENL += (allResFields.length * DESTROY_FIELD);
|
||||
allEnlFields = uniqueArray(allEnlFields);
|
||||
totalAP_RES += (allEnlFields.length * DESTROY_FIELD);
|
||||
|
||||
// Compute team Link AP
|
||||
allResEdges = uniqueArray(allResEdges);
|
||||
totalAP_ENL += (allResEdges.length * DESTROY_LINK);
|
||||
allEnlEdges = uniqueArray(allEnlEdges);
|
||||
totalAP_RES += (allEnlEdges.length * DESTROY_LINK);
|
||||
|
||||
return [totalAP_RES, totalAP_ENL];
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.plugin.compAPStats.setupCallback();
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-raw-portal-data
|
||||
// @name IITC plugin: Debug: Raw portal JSON data
|
||||
// @category Debug
|
||||
// @version 0.2.2.@@DATETIMEVERSION@@
|
||||
// @version 0.2.3.@@DATETIMEVERSION@@
|
||||
// @namespace rawdata
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -36,40 +36,43 @@ window.plugin.rawdata.showPortalData = function(guid) {
|
||||
}
|
||||
|
||||
|
||||
var d = window.portals[guid].options.details;
|
||||
var data = window.portals[guid].options.data;
|
||||
var ts = window.portals[guid].options.timestamp;
|
||||
|
||||
var title = 'Raw portal data: ' + (d.portalV2.descriptiveText.TITLE || '<no title>') + ' ('+guid+')';
|
||||
var title = 'Raw portal data: ' + (data.title || '<no title>') + ' ('+guid+')';
|
||||
|
||||
var body =
|
||||
'<b>Portal GUID</b>: <code>'+guid+'</code><br />' +
|
||||
'<b>Entity timestamp</b>: <code>'+ts+'</code> - '+window.unixTimeToDateTimeString(ts,true)+'<br />' +
|
||||
'<pre>'+JSON.stringify(d,null,2)+'</pre>';
|
||||
'<pre>'+JSON.stringify(data,null,2)+'</pre>';
|
||||
|
||||
var details = portalDetail.get(guid);
|
||||
if (details) {
|
||||
body += '<b>Portal details:</b><pre>'+JSON.stringify(details,null,2)+'</pre>';
|
||||
}
|
||||
|
||||
|
||||
body += '<p><b>Links referencing this portal</b></p>';
|
||||
var haslinks = false;
|
||||
for (var lguid in window.links) {
|
||||
var linkGuids = getPortalLinks(guid);
|
||||
$.each(linkGuids.in.concat(linkGuids.out), function(i,lguid) {
|
||||
var l = window.links[lguid];
|
||||
var ld = l.options.details;
|
||||
if (ld.edge.originPortalGuid == guid || ld.edge.destinationPortalGuid == guid) {
|
||||
body += '<b>Link GUID</b>: <code>'+l.options.guid+'</code><br /><pre>'+JSON.stringify(ld,null,2)+'</pre>';
|
||||
haslinks = true;
|
||||
}
|
||||
}
|
||||
var ld = l.options.data;
|
||||
body += '<b>Link GUID</b>: <code>'+l.options.guid+'</code><br /><pre>'+JSON.stringify(ld,null,2)+'</pre>';
|
||||
haslinks = true;
|
||||
});
|
||||
|
||||
if (!haslinks) body += '<p>No links to/from this portal</p>';
|
||||
|
||||
body += '<p><b>Fields referencing this portal</b></p>';
|
||||
var hasfields = false;
|
||||
for (var fguid in window.fields) {
|
||||
var fieldGuids = getPortalFields(guid);
|
||||
$.each(fieldGuids, function(i,fguid) {
|
||||
var f = window.fields[fguid];
|
||||
var fd = f.options.details;
|
||||
if (fd.capturedRegion.vertexA.guid == guid ||
|
||||
fd.capturedRegion.vertexB.guid == guid ||
|
||||
fd.capturedRegion.vertexC.guid == guid) {
|
||||
body += '<b>Field guid</b>: <code>'+f.options.guid+'</code><br /><pre>'+JSON.stringify(fd,null,2)+'</pre>';
|
||||
hasfields = true;
|
||||
}
|
||||
}
|
||||
var fd = f.options.data;
|
||||
body += '<b>Field guid</b>: <code>'+f.options.guid+'</code><br /><pre>'+JSON.stringify(fd,null,2)+'</pre>';
|
||||
hasfields = true;
|
||||
});
|
||||
if (!hasfields) body += '<p>No fields linked to this portal</p>';
|
||||
|
||||
dialog({
|
||||
|
@ -1,811 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-draw-resonators@xelio
|
||||
// @name IITC plugin: Draw resonators
|
||||
// @category Layer
|
||||
// @category Deleted
|
||||
// @version 0.4.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Draw resonators on map. With stylers to highlight resonators with specific criteria.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.drawResonators = function() {};
|
||||
|
||||
|
||||
window.plugin.drawResonators.options;
|
||||
window.plugin.drawResonators.render;
|
||||
|
||||
|
||||
|
||||
//////// Render for handling render of resonators ////////
|
||||
|
||||
// As long as 'window.Render.prototype.createPortalEntity' delete and recreate portal
|
||||
// on any change of data, this resonator render should make resonator create and remove
|
||||
// with portal correctly.
|
||||
//
|
||||
// Resonators will create when
|
||||
// 1.Portal added to map
|
||||
// 2.Zooming in to enable zoom level
|
||||
//
|
||||
// Resonators will remove when
|
||||
// 1.Portal removed from map
|
||||
// 2.Zooming out beyond enable zoom level
|
||||
|
||||
window.plugin.drawResonators.Render = function(options) {
|
||||
this.enableZoomLevel = options['enableZoomLevel'];
|
||||
this.useStyler = '';
|
||||
|
||||
this.stylers = {};
|
||||
this.resonators = {};
|
||||
this.resonatorLayerGroup = new L.LayerGroup();
|
||||
this.addStyler(new window.plugin.drawResonators.Styler());
|
||||
this.beforeZoomLevel = map.getZoom();
|
||||
|
||||
this.portalAdded = this.portalAdded.bind(this);
|
||||
this.createResonatorEntities = this.createResonatorEntities.bind(this);
|
||||
this.deleteResonatorEntities = this.deleteResonatorEntities.bind(this);
|
||||
this.handleResonatorEntitiesBeforeZoom = this.handleResonatorEntitiesBeforeZoom.bind(this);
|
||||
this.handleResonatorEntitiesAfterZoom = this.handleResonatorEntitiesAfterZoom.bind(this);
|
||||
this.handleEnableZoomLevelChange = this.handleEnableZoomLevelChange.bind(this);
|
||||
this.portalSelectionChange = this.portalSelectionChange.bind(this);
|
||||
this.changeStyler = this.changeStyler.bind(this);
|
||||
this.getStylersList = this.getStylersList.bind(this);
|
||||
};
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.registerHook = function() {
|
||||
window.addHook('portalAdded', this.portalAdded);
|
||||
window.addHook('portalSelected', this.portalSelectionChange);
|
||||
window.map.on('zoomstart', this.handleResonatorEntitiesBeforeZoom);
|
||||
window.map.on('zoomend', this.handleResonatorEntitiesAfterZoom);
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.portalAdded = function(data) {
|
||||
var marker = data.portal;
|
||||
var render = this;
|
||||
|
||||
marker.on('add', function() {
|
||||
render.createResonatorEntities(this); // the 'this' in here is the portal.
|
||||
});
|
||||
|
||||
marker.on('remove', function() {
|
||||
render.deleteResonatorEntities(this.options.guid); // the 'this' in here is the portal.
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.createResonatorEntities = function(portal) {
|
||||
// No need to check for existing resonators, as old resonators should be removed with the portal marker.
|
||||
|
||||
if(!this.isResonatorsShow()) return;
|
||||
var portalDetails = portal.options.details;
|
||||
var resonatorsWithConnector = new L.LayerGroup()
|
||||
|
||||
var portalLatLng = [portalDetails.locationE6.latE6/1E6, portalDetails.locationE6.lngE6/1E6];
|
||||
var portalSelected = selectedPortal === portal.options.guid;
|
||||
|
||||
for(var i in portalDetails.resonatorArray.resonators) {
|
||||
resoData = portalDetails.resonatorArray.resonators[i];
|
||||
if(resoData === null) continue;
|
||||
|
||||
var resoLatLng = this.getResonatorLatLng(resoData.distanceToPortal, resoData.slot, portalLatLng);
|
||||
|
||||
var resoMarker = this.createResoMarker(resoData, resoLatLng, portalSelected);
|
||||
var connMarker = this.createConnMarker(resoData, resoLatLng, portalLatLng, portalSelected);
|
||||
|
||||
resonatorsWithConnector.addLayer(resoMarker);
|
||||
resonatorsWithConnector.addLayer(connMarker);
|
||||
}
|
||||
|
||||
resonatorsWithConnector.options = {
|
||||
details: portalDetails.resonatorArray.resonators,
|
||||
guid: portal.options.guid
|
||||
};
|
||||
|
||||
this.resonators[portal.options.guid] = resonatorsWithConnector;
|
||||
this.resonatorLayerGroup.addLayer(resonatorsWithConnector);
|
||||
|
||||
// bring portal in front of resonator connector
|
||||
portal.bringToFront();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.createResoMarker = function(resoData, resoLatLng, portalSelected) {
|
||||
var resoProperty = this.getStyler().getResonatorStyle(resoData, portalSelected);
|
||||
resoProperty.type = 'resonator';
|
||||
resoProperty.details = resoData;
|
||||
var reso = L.circleMarker(resoLatLng, resoProperty);
|
||||
return reso;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.createConnMarker = function(resoData, resoLatLng, portalLatLng, portalSelected) {
|
||||
var connProperty = this.getStyler().getConnectorStyle(resoData, portalSelected);
|
||||
connProperty.type = 'connector';
|
||||
connProperty.details = resoData;
|
||||
var conn = L.polyline([portalLatLng, resoLatLng], connProperty);
|
||||
return conn;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.getResonatorLatLng = function(dist, slot, portalLatLng) {
|
||||
// offset in meters
|
||||
var dn = dist*SLOT_TO_LAT[slot];
|
||||
var de = dist*SLOT_TO_LNG[slot];
|
||||
|
||||
// Coordinate offset in radians
|
||||
var dLat = dn/EARTH_RADIUS;
|
||||
var dLon = de/(EARTH_RADIUS*Math.cos(Math.PI/180*portalLatLng[0]));
|
||||
|
||||
// OffsetPosition, decimal degrees
|
||||
var lat0 = portalLatLng[0] + dLat * 180/Math.PI;
|
||||
var lon0 = portalLatLng[1] + dLon * 180/Math.PI;
|
||||
|
||||
return [lat0, lon0];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.deleteResonatorEntities = function(portalGuid) {
|
||||
if (!(portalGuid in this.resonators)) return;
|
||||
|
||||
var r = this.resonators[portalGuid];
|
||||
this.resonatorLayerGroup.removeLayer(r);
|
||||
delete this.resonators[portalGuid];
|
||||
}
|
||||
|
||||
// Save zoom level before zoom, use to determine redraw of resonator
|
||||
window.plugin.drawResonators.Render.prototype.handleResonatorEntitiesBeforeZoom = function() {
|
||||
this.beforeZoomLevel = map.getZoom();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.handleResonatorEntitiesAfterZoom = function() {
|
||||
if(!this.isResonatorsShow()) {
|
||||
this.clearAllResonators();
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw all resonators if they were not drawn
|
||||
if(!this.isResonatorsShowBeforeZoom()) {
|
||||
this.drawAllResonators();
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.handleEnableZoomLevelChange = function(zoomLevel) {
|
||||
this.enableZoomLevel = zoomLevel;
|
||||
|
||||
if(!this.isResonatorsShow()) {
|
||||
this.clearAllResonators();
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw all resonators if they were not drawn
|
||||
if(!Object.keys(this.resonators).length > 0) {
|
||||
this.drawAllResonators();
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.clearAllResonators = function() {
|
||||
this.resonatorLayerGroup.clearLayers();
|
||||
this.resonators = {};
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.drawAllResonators = function() {
|
||||
var render = this;
|
||||
|
||||
// loop through level of portals, only draw if the portal is shown on map
|
||||
for (var guid in window.portals) {
|
||||
var portal = window.portals[guid];
|
||||
// FIXME: need to find a proper way to check if a portal is added to the map without depending on leaflet internals
|
||||
// (and without depending on portalsLayers either - that's IITC internal)
|
||||
if (portal._map) {
|
||||
render.createResonatorEntities(portal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.portalSelectionChange = function(data) {
|
||||
this.toggleSelectedStyle(data.selectedPortalGuid);
|
||||
this.toggleSelectedStyle(data.unselectedPortalGuid);
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.toggleSelectedStyle = function(portalGuid) {
|
||||
if (!(portalGuid in this.resonators)) return;
|
||||
|
||||
var render = this;
|
||||
var portalSelected = selectedPortal === portalGuid;
|
||||
var r = this.resonators[portalGuid];
|
||||
|
||||
r.eachLayer(function(entity) {
|
||||
var style;
|
||||
if(entity.options.type === 'resonator') {
|
||||
style = render.getStyler().getResonatorStyle(entity.options.details, portalSelected);
|
||||
} else {
|
||||
style = render.getStyler().getConnectorStyle(entity.options.details, portalSelected);
|
||||
}
|
||||
|
||||
entity.setStyle(style);
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.addStyler = function(styler) {
|
||||
this.stylers[styler.name] = styler;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.getStylersList = function() {
|
||||
return Object.keys(this.stylers);
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.getStyler = function() {
|
||||
var stylerName = this.useStyler in this.stylers ? this.useStyler : 'Default';
|
||||
return this.stylers[stylerName];
|
||||
}
|
||||
|
||||
// Change if styler need change, and redraw all resonators using new styler
|
||||
window.plugin.drawResonators.Render.prototype.changeStyler = function(name) {
|
||||
if (name === this.useStyler) return;
|
||||
for(stylerName in this.stylers) {
|
||||
if(stylerName === name) {
|
||||
if(this.stylers[this.useStyler]) this.stylers[this.useStyler].onDisableFunc();
|
||||
this.useStyler = stylerName;
|
||||
this.stylers[this.useStyler].onEnableFunc();
|
||||
this.clearAllResonators();
|
||||
this.drawAllResonators();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.refreshStyler = function() {
|
||||
this.clearAllResonators();
|
||||
this.drawAllResonators();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.isResonatorsShow = function() {
|
||||
return map.getZoom() >= this.enableZoomLevel;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Render.prototype.isResonatorsShowBeforeZoom = function() {
|
||||
return this.beforeZoomLevel >= this.enableZoomLevel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// Styler for getting resonator and connector style ////////
|
||||
|
||||
|
||||
|
||||
window.plugin.drawResonators.Styler = function(options) {
|
||||
options = options || {};
|
||||
this.name = options['name'] || 'Default';
|
||||
this.otherOptions = options['otherOptions'];
|
||||
this.getResonatorStyle = options['resonatorStyleFunc'] || this.defaultResonatorStyle;
|
||||
this.getConnectorStyle = options['connectorStyleFunc'] || this.defaultConnectorStyle;
|
||||
this.onEnableFunc = options['onEnableFunc'] || function() {};
|
||||
this.onDisableFunc = options['onDisableFunc'] || function() {};
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_SELECTED = {
|
||||
color: '#fff',
|
||||
weight: 1.1,
|
||||
radius: 4,
|
||||
opacity: 1,
|
||||
clickable: false};
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_NON_SELECTED = {
|
||||
color: '#aaa',
|
||||
weight: 1,
|
||||
radius: 3,
|
||||
opacity: 1,
|
||||
clickable: false};
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_LINE_SELECTED = {
|
||||
opacity: 0.7,
|
||||
weight: 3,
|
||||
color: '#FFA000',
|
||||
dashArray: '0,10' + (new Array(25).join(',8,4')),
|
||||
fill: false,
|
||||
clickable: false};
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_LINE_NON_SELECTED = {
|
||||
opacity: 0.25,
|
||||
weight: 2,
|
||||
color: '#FFA000',
|
||||
dashArray: '0,10' + (new Array(25).join(',8,4')),
|
||||
fill: false,
|
||||
clickable: false};
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.defaultResonatorStyle = function(resoDetail, selected) {
|
||||
var resoSharedStyle = selected
|
||||
? this.DEFAULT_OPTIONS_RESONATOR_SELECTED
|
||||
: this.DEFAULT_OPTIONS_RESONATOR_NON_SELECTED;
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level],
|
||||
}, resoSharedStyle);
|
||||
|
||||
return resoStyle;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Styler.prototype.defaultConnectorStyle = function(resoDetail, selected) {
|
||||
var connStyle = selected
|
||||
? this.DEFAULT_OPTIONS_RESONATOR_LINE_SELECTED
|
||||
: this.DEFAULT_OPTIONS_RESONATOR_LINE_NON_SELECTED;
|
||||
|
||||
return connStyle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// Options for storing and loading options ////////
|
||||
|
||||
|
||||
|
||||
window.plugin.drawResonators.Options = function() {
|
||||
this._options = {};
|
||||
this._callbacks = {};
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.addCallback = function(name, callback) {
|
||||
if (!this._callbacks[name]) {
|
||||
this._callbacks[name] = [];
|
||||
}
|
||||
this._callbacks[name].push(callback);
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.newOption = function(name, defaultValue) {
|
||||
this._options[name] = this.loadLocal(this.getStorageKey(name), defaultValue)
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.getOption = function(name) {
|
||||
return this._options[name];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.removeOption = function(name) {
|
||||
delete this._options[name];
|
||||
delete this._callbacks[name];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.changeOption = function(name, value) {
|
||||
if(!(name in this._options)) return false;
|
||||
if(value === this._options[name]) return false;
|
||||
|
||||
this._options[name] = value;
|
||||
this.storeLocal(this.getStorageKey(name), this._options[name]);
|
||||
|
||||
if (this._callbacks[name] !== null) {
|
||||
for(var i in this._callbacks[name]) {
|
||||
this._callbacks[name][i](value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.getStorageKey = function(name) {
|
||||
return 'plugin-drawResonators-option-' + name;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.loadLocal = function(key, defaultValue) {
|
||||
var objectJSON = localStorage[key];
|
||||
if(objectJSON) {
|
||||
return JSON.parse(objectJSON);
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Options.prototype.storeLocal = function(key, value) {
|
||||
if(typeof(value) !== 'undefined' && value !== null) {
|
||||
localStorage[key] = JSON.stringify(value);
|
||||
} else {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// Dialog
|
||||
|
||||
window.plugin.drawResonators.Dialog = function() {
|
||||
this._dialogEntries = {};
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.addLink = function() {
|
||||
$('#toolbox').append('<a id="draw-reso-show-dialog" onclick="window.plugin.drawResonators.dialog.show();">Resonators</a> ');
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.addEntry = function(name, dialogEntry) {
|
||||
this._dialogEntries[name] = dialogEntry;
|
||||
this.change();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.removeEntry = function(name) {
|
||||
delete this._dialogEntries[name];
|
||||
this.change();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.show = function() {
|
||||
window.dialog({html: this.getDialogHTML(), title: 'Resonators', modal: true, id: 'draw-reso-setting'});
|
||||
|
||||
// Attach entries event
|
||||
for(var name in this._dialogEntries) {
|
||||
var events = this._dialogEntries[name].getOnEvents();
|
||||
for(var i in events) {
|
||||
var event = events[i];
|
||||
$('#draw-reso-dialog').on(event.event, '#' + event.id, event.callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.change = function() {
|
||||
if($('#draw-reso-dialog').length > 0) this.show();
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.Dialog.prototype.getDialogHTML = function() {
|
||||
var html = '<div id="draw-reso-dialog">'
|
||||
for(var name in this._dialogEntries) {
|
||||
html += '<div>'
|
||||
+ this._dialogEntries[name].getHTML()
|
||||
+ '</div>';
|
||||
}
|
||||
html += '</div>';
|
||||
return html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// ListDialogEntry
|
||||
|
||||
|
||||
|
||||
window.plugin.drawResonators.ListDialogEntry = function(options) {
|
||||
this._name = options['name'];
|
||||
this._label = options['label'];
|
||||
this._valueFunc = options['valueFunc'];
|
||||
this._valuesList = options['valuesList'];
|
||||
this._valuesListFunc = options['valuesListFunc'];
|
||||
this._onChangeCallback = options['onChangeCallback'];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.ListDialogEntry.prototype.getHTML = function() {
|
||||
var curValue = this._valueFunc();
|
||||
var valuesList = this._valuesList ? this._valuesList : this._valuesListFunc();
|
||||
var html = '<label for="' + this.getSelectId() + '">'
|
||||
+ this._label + ': '
|
||||
+ '</label>'
|
||||
+ '<select id="' + this.getSelectId() + '">';
|
||||
|
||||
var noLabel = valuesList instanceof Array;
|
||||
for(var label in valuesList) {
|
||||
var selected = valuesList[label] === curValue;
|
||||
html += '<option value="' + valuesList[label] + '" '
|
||||
+ (selected ? 'selected="selected"' : '')
|
||||
+'>'
|
||||
+ (noLabel ? valuesList[label] : label)
|
||||
+ '</option>';
|
||||
}
|
||||
|
||||
html += '</select>';
|
||||
return html;
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.ListDialogEntry.prototype.getOnEvents = function() {
|
||||
return [{'event': 'change',
|
||||
'id': this.getSelectId(),
|
||||
'callback': this._onChangeCallback
|
||||
}];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.ListDialogEntry.prototype.getSelectId = function() {
|
||||
return 'draw-reso-option-' + this._name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////// TextboxDialogEntry
|
||||
|
||||
|
||||
window.plugin.drawResonators.TextboxDialogEntry = function(options) {
|
||||
this._name = options['name'];
|
||||
this._label = options['label'];
|
||||
this._valueFunc = options['valueFunc'];
|
||||
this._onChangeCallback = options['onChangeCallback'];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.TextboxDialogEntry.prototype.getHTML = function() {
|
||||
var curValue = this._valueFunc();
|
||||
var html = '<label for="' + this.getInputId() + '">'
|
||||
+ this._label + ': '
|
||||
+ '</label>'
|
||||
+ '<input type="text" size="20" id="' + this.getInputId() + '" '
|
||||
+ 'value="' + curValue + '" />';
|
||||
return html;
|
||||
}
|
||||
|
||||
|
||||
window.plugin.drawResonators.TextboxDialogEntry.prototype.getOnEvents = function() {
|
||||
return [{'event': 'change',
|
||||
'id': this.getInputId(),
|
||||
'callback': this._onChangeCallback
|
||||
}];
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.TextboxDialogEntry.prototype.getInputId = function() {
|
||||
return 'draw-reso-option-' + this._name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.plugin.drawResonators.setupStyler = function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
|
||||
var highlightedReso = {color: '#fff', weight: 2, radius: 4, opacity: 1, clickable: false};
|
||||
var normalReso = {color: '#aaa', weight: 1, radius: 3, opacity: 1, clickable: false};
|
||||
var selectedReso = {color: '#eee', weight: 1.1, radius: 4, opacity: 1, clickable: false};
|
||||
var highlightedConn = {opacity: 0.7, weight: 3, color: '#FFA000', dashArray: '0,10,999', color: '#FFA000', fill: false, clickable: false};
|
||||
var normalConn = {opacity: 0.25, weight: 2, color: '#FFA000', dashArray: '0,10' + (new Array(25).join(',8,4')), fill: false, clickable: false};
|
||||
var selectedConn = {opacity: 0.7, weight: 3, color: '#FFA000', dashArray: '0,10' + (new Array(25).join(',8,4')), fill: false, clickable: false};
|
||||
|
||||
// Styler for highlighting resonators deployed by me
|
||||
var myReso = {
|
||||
name: 'Highlight my resonators',
|
||||
otherOptions: {
|
||||
'highlightedReso' : highlightedReso,
|
||||
'normalReso' : normalReso,
|
||||
'selectedReso' : selectedReso,
|
||||
'highlightedConn' : highlightedConn,
|
||||
'normalConn' : normalConn,
|
||||
'selectedConn' : selectedConn
|
||||
},
|
||||
resonatorStyleFunc: function(resoDetail, selected) {
|
||||
var mine = resoDetail.ownerGuid === PLAYER.guid;
|
||||
var resoSharedStyle = mine
|
||||
? this.otherOptions.highlightedReso
|
||||
: (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso);
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] * (mine ? 1 : 0.75)
|
||||
}, resoSharedStyle);
|
||||
return resoStyle;
|
||||
},
|
||||
connectorStyleFunc: function(resoDetail, selected) {
|
||||
var mine = resoDetail.ownerGuid === PLAYER.guid;
|
||||
var connStyle = mine
|
||||
? this.otherOptions.highlightedConn
|
||||
: (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn);
|
||||
return connStyle;
|
||||
}
|
||||
};
|
||||
|
||||
thisPlugin.render.addStyler(new thisPlugin.Styler(myReso));
|
||||
|
||||
// Styler for highlighting L8 resonators
|
||||
var l8Reso = {
|
||||
name: 'Highlight L8 resonators',
|
||||
otherOptions: {
|
||||
'highlightedReso' : highlightedReso,
|
||||
'normalReso' : normalReso,
|
||||
'selectedReso' : selectedReso,
|
||||
'highlightedConn' : highlightedConn,
|
||||
'normalConn' : normalConn,
|
||||
'selectedConn' : selectedConn
|
||||
},
|
||||
resonatorStyleFunc: function(resoDetail, selected) {
|
||||
var l8 = resoDetail.level === 8;
|
||||
var resoSharedStyle = l8
|
||||
? this.otherOptions.highlightedReso
|
||||
: (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso);
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] * (l8 ? 1 : 0.75)
|
||||
}, resoSharedStyle);
|
||||
return resoStyle;
|
||||
},
|
||||
connectorStyleFunc: function(resoDetail, selected) {
|
||||
var l8 = resoDetail.level === 8;
|
||||
var connStyle = l8
|
||||
? this.otherOptions.highlightedConn
|
||||
: (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn);
|
||||
return connStyle;
|
||||
}
|
||||
};
|
||||
|
||||
thisPlugin.render.addStyler(new thisPlugin.Styler(l8Reso));
|
||||
|
||||
// Styler for highlighting resonators with less than X% energy
|
||||
var lessThanXPctReso = {
|
||||
name: 'Highlight < X% resonators',
|
||||
otherOptions: {
|
||||
'highlightedReso': highlightedReso,
|
||||
'normalReso': normalReso,
|
||||
'selectedReso': selectedReso,
|
||||
'highlightedConn': highlightedConn,
|
||||
'normalConn': normalConn,
|
||||
'selectedConn': selectedConn,
|
||||
'pct': 15,
|
||||
'dialogEntry': new thisPlugin.TextboxDialogEntry({
|
||||
name: 'resoLessThanPct-pct',
|
||||
label: 'Percentage',
|
||||
valueFunc: function() {return thisPlugin.options.getOption('styler-resoLessThanPct-pct')},
|
||||
onChangeCallback: function(event) {thisPlugin.options.changeOption('styler-resoLessThanPct-pct', parseInt(event.target.value));}
|
||||
})
|
||||
},
|
||||
resonatorStyleFunc: function(resoDetail, selected) {
|
||||
var highlight = (resoDetail.energyTotal * 100) < (RESO_NRG[resoDetail.level] * this.otherOptions.pct);
|
||||
var resoSharedStyle = highlight
|
||||
? this.otherOptions.highlightedReso
|
||||
: (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso);
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level]
|
||||
}, resoSharedStyle);
|
||||
return resoStyle;
|
||||
},
|
||||
connectorStyleFunc: function(resoDetail, selected) {
|
||||
var highlight = (resoDetail.energyTotal * 100) < (RESO_NRG[resoDetail.level] * this.otherOptions.pct);
|
||||
var connStyle = highlight
|
||||
? this.otherOptions.highlightedConn
|
||||
: (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn);
|
||||
return connStyle;
|
||||
},
|
||||
onEnableFunc: function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
var thisStyler = this;
|
||||
// Add option
|
||||
thisPlugin.options.newOption('styler-resoLessThanPct-pct', 15);
|
||||
thisPlugin.options.addCallback('styler-resoLessThanPct-pct', function(value) {
|
||||
thisStyler.otherOptions.pct = value;
|
||||
thisPlugin.render.refreshStyler();
|
||||
});
|
||||
thisStyler.otherOptions.pct = thisPlugin.options.getOption('styler-resoLessThanPct-pct');
|
||||
// Add dialog entry
|
||||
thisPlugin.dialog.addEntry('resoLessThanPct-pct', this.otherOptions.dialogEntry);
|
||||
},
|
||||
onDisableFunc: function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
// Remove option
|
||||
thisPlugin.options.removeOption('styler-resoLessThanPct-pct');
|
||||
// Remove dialog entry
|
||||
thisPlugin.dialog.removeEntry('resoLessThanPct-pct');
|
||||
}
|
||||
};
|
||||
|
||||
thisPlugin.render.addStyler(new thisPlugin.Styler(lessThanXPctReso));
|
||||
|
||||
// Styler for highlighting resonators deployed by specific player
|
||||
var resoOfSpecificPlayer = {
|
||||
name: 'Highlight resonators by player',
|
||||
otherOptions: {
|
||||
'highlightedReso': highlightedReso,
|
||||
'normalReso': normalReso,
|
||||
'selectedReso': selectedReso,
|
||||
'highlightedConn': highlightedConn,
|
||||
'normalConn': normalConn,
|
||||
'selectedConn': selectedConn,
|
||||
'player': '',
|
||||
'playerGuid': '',
|
||||
'dialogEntry': new thisPlugin.TextboxDialogEntry({
|
||||
name: 'resoOfSpecificPlayer-player',
|
||||
label: 'Player name',
|
||||
valueFunc: function() {return thisPlugin.options.getOption('styler-resoOfSpecificPlayer-player')},
|
||||
onChangeCallback: function(event) {thisPlugin.options.changeOption('styler-resoOfSpecificPlayer-player', event.target.value);}
|
||||
})
|
||||
},
|
||||
resonatorStyleFunc: function(resoDetail, selected) {
|
||||
var highlight = resoDetail.ownerGuid === this.otherOptions.playerGuid;
|
||||
var resoSharedStyle = highlight
|
||||
? this.otherOptions.highlightedReso
|
||||
: (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso);
|
||||
|
||||
var resoStyle = $.extend({
|
||||
fillColor: COLORS_LVL[resoDetail.level],
|
||||
fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] * (highlight ? 1 : 0.75)
|
||||
}, resoSharedStyle);
|
||||
return resoStyle;
|
||||
},
|
||||
connectorStyleFunc: function(resoDetail, selected) {
|
||||
var highlight = resoDetail.ownerGuid === this.otherOptions.playerGuid;
|
||||
var connStyle = highlight
|
||||
? this.otherOptions.highlightedConn
|
||||
: (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn);
|
||||
return connStyle;
|
||||
},
|
||||
onEnableFunc: function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
var thisStyler = this;
|
||||
// Add option
|
||||
thisPlugin.options.newOption('styler-resoOfSpecificPlayer-player', '');
|
||||
thisPlugin.options.addCallback('styler-resoOfSpecificPlayer-player', function(value) {
|
||||
thisStyler.otherOptions.player = value;
|
||||
thisStyler.otherOptions.playerGuid = window.playerNameToGuid(value);
|
||||
thisPlugin.render.refreshStyler();
|
||||
});
|
||||
thisStyler.otherOptions.player = thisPlugin.options.getOption('styler-resoOfSpecificPlayer-player');
|
||||
thisStyler.otherOptions.playerGuid = window.playerNameToGuid(thisStyler.otherOptions.player);
|
||||
// Add dialog entry
|
||||
thisPlugin.dialog.addEntry('resoOfSpecificPlayer-player', this.otherOptions.dialogEntry);
|
||||
},
|
||||
onDisableFunc: function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
// Remove option
|
||||
thisPlugin.options.removeOption('styler-resoOfSpecificPlayer-player');
|
||||
// Remove dialog entry
|
||||
thisPlugin.dialog.removeEntry('resoOfSpecificPlayer-player');
|
||||
}
|
||||
};
|
||||
|
||||
thisPlugin.render.addStyler(new thisPlugin.Styler(resoOfSpecificPlayer));
|
||||
|
||||
thisPlugin.render.changeStyler(thisPlugin.options.getOption('useStyler'));
|
||||
}
|
||||
|
||||
|
||||
window.plugin.drawResonators.setupOptions = function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
// Initialize options
|
||||
thisPlugin.options = new thisPlugin.Options();
|
||||
thisPlugin.options.newOption('enableZoomLevel', 17);
|
||||
thisPlugin.options.newOption('useStyler', 'Default');
|
||||
}
|
||||
|
||||
window.plugin.drawResonators.setupDialog = function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
// Initialize dialog
|
||||
thisPlugin.dialog = new thisPlugin.Dialog();
|
||||
|
||||
var enableZoomLevelDialogEntryOptions = {
|
||||
name: 'enable-zoom-level',
|
||||
label: 'Enable zoom level',
|
||||
valueFunc: function() {return thisPlugin.options.getOption('enableZoomLevel')},
|
||||
valuesList: {'15':15, '16':16, '17':17, '18':18, '19':19, '20':20, 'None':99},
|
||||
onChangeCallback: function(event) {thisPlugin.options.changeOption('enableZoomLevel', parseInt(event.target.value));}
|
||||
};
|
||||
var enableZoomLevelDialogEntry = new thisPlugin.ListDialogEntry(enableZoomLevelDialogEntryOptions);
|
||||
thisPlugin.dialog.addEntry('enable-zoom-level', enableZoomLevelDialogEntry);
|
||||
|
||||
var stylerDialogEntryOptions = {
|
||||
name: 'use-styler',
|
||||
label: 'Styler',
|
||||
valueFunc: function() {return thisPlugin.options.getOption('useStyler')},
|
||||
valuesListFunc: thisPlugin.render.getStylersList,
|
||||
onChangeCallback: function(event) {thisPlugin.options.changeOption('useStyler', event.target.value);}
|
||||
};
|
||||
var stylerDialogEntry = new thisPlugin.ListDialogEntry(stylerDialogEntryOptions);
|
||||
thisPlugin.dialog.addEntry('use-styler', stylerDialogEntry);
|
||||
|
||||
thisPlugin.dialog.addLink();
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
var thisPlugin = window.plugin.drawResonators;
|
||||
|
||||
// Initialize options
|
||||
thisPlugin.setupOptions();
|
||||
|
||||
// Initialize render
|
||||
var renderOptions = {'enableZoomLevel': thisPlugin.options.getOption('enableZoomLevel')};
|
||||
|
||||
thisPlugin.render = new thisPlugin.Render(renderOptions);
|
||||
|
||||
// callback run at option change
|
||||
thisPlugin.options.addCallback('enableZoomLevel', thisPlugin.render.handleEnableZoomLevelChange);
|
||||
thisPlugin.options.addCallback('useStyler', thisPlugin.render.changeStyler);
|
||||
|
||||
// Initialize Dialog
|
||||
thisPlugin.setupDialog();
|
||||
// Initialize styler
|
||||
thisPlugin.setupStyler();
|
||||
|
||||
thisPlugin.render.registerHook();
|
||||
window.addLayerGroup('Resonators', thisPlugin.render.resonatorLayerGroup, true);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,9 +1,9 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-favorite-portals@soulBit
|
||||
// @name IITC plugin: Favorite Portals
|
||||
// @category Obsolete
|
||||
// @category Deleted
|
||||
// @version 0.2.0.@@DATETIMEVERSION@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] DEPRECATED. Please use "Bookmarks for maps and portals" instead.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -13,161 +13,3 @@
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
window.plugin.favoritePortals = function() {};
|
||||
|
||||
window.plugin.favoritePortals.portalList = {};
|
||||
window.plugin.favoritePortals.LOCAL_STORAGE_KEY = "plugin-favorite-portals";
|
||||
window.plugin.favoritePortals.hasLocalStorage = ('localStorage' in window && window['localStorage'] !== null);
|
||||
|
||||
window.plugin.favoritePortals.onDetailsUpdated = function(data) {
|
||||
$('.linkdetails').prepend("<div title='Favorite this portal' class='toggle-favorite-portal' onclick='window.plugin.favoritePortals.togglePortal()' />");
|
||||
if(window.plugin.favoritePortals.portalList[window.selectedPortal]) {
|
||||
$('.toggle-favorite-portal').addClass( 'portal-on' );
|
||||
window.plugin.favoritePortals.portalList[window.selectedPortal] = window.portals[window.selectedPortal].options;
|
||||
window.plugin.favoritePortals.savePortals();
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.display = function() {
|
||||
var output = '';
|
||||
|
||||
if (!window.plugin.favoritePortals.hasLocalStorage) {
|
||||
output += "Favorite portals cannot save any data, please try another browser that supports 'localStorage'.";
|
||||
} else {
|
||||
if ($.isEmptyObject(window.plugin.favoritePortals.portalList)) {
|
||||
output += "No portals have been marked as favorite, click the blue square in the bottom left corner of the portal details to save one.";
|
||||
} else {
|
||||
output += "<div class='header'>Portal list (values not current till portal on screen):</div>";
|
||||
output += "<div class='portal-list-container'>";
|
||||
|
||||
var portals = [], dataChanged = false, portalData;
|
||||
$.each( window.plugin.favoritePortals.portalList, function(i, portal) {
|
||||
if(window.portals[i]) {
|
||||
dataChanged = true;
|
||||
window.plugin.favoritePortals.portalList[ i ] = window.portals[i].options;
|
||||
}
|
||||
portalData = (window.portals[i]) ? window.portals[i].options : portal;
|
||||
portals.push({'guid': i, 'portalData': portalData});
|
||||
});
|
||||
if(dataChanged)
|
||||
window.plugin.favoritePortals.savePortals();
|
||||
|
||||
portals.sort(function(a,b) {
|
||||
var nameA = a.portalData.details.portalV2.descriptiveText.TITLE.toLowerCase();
|
||||
var nameB = b.portalData.details.portalV2.descriptiveText.TITLE.toLowerCase();
|
||||
return (nameA < nameB) ? -1 : (nameA > nameB) ? 1 : 0;
|
||||
});
|
||||
|
||||
output += "<ol>";
|
||||
var teamName, energy;
|
||||
$.each(portals, function(i, portal) {
|
||||
portalData = portal.portalData;
|
||||
output += "<li name='" + portal.guid + "'>";
|
||||
|
||||
output += "<a class='delete-favorite-portal' title='Delete favorite?' onclick='window.plugin.favoritePortals.onDelete(" + '"' + portal.guid + '"' + ");return false'>X</a>";
|
||||
output += "<a onclick='window.plugin.favoritePortals.onPortalClicked(" + ' "' + portal.guid + '", [' + (portalData.details.locationE6.latE6 / 1000000) + "," + (portal.portalData.details.locationE6.lngE6 / 1000000) + "]);return false'>" + portalData.details.portalV2.descriptiveText.TITLE + "</a>";
|
||||
teamName = portalData.details.controllingTeam.team;
|
||||
output += " - L" + Math.floor( portalData.level );
|
||||
energy = Math.floor( window.getCurrentPortalEnergy(portalData.details) / window.getPortalEnergy(portalData.details) * 100 );
|
||||
if(!isNaN(energy))
|
||||
output += " @" + energy + "%";
|
||||
output += ": " + ( (teamName === "ALIENS") ? "Enlightened" : teamName[0] + teamName.slice(1).toLowerCase() );
|
||||
if(portalData.details.portalV2.linkedEdges.length > 0 || portalData.details.portalV2.linkedFields.length > 0)
|
||||
output += ", " + portalData.details.portalV2.linkedEdges.length + " links & " + portalData.details.portalV2.linkedFields.length + " fields";
|
||||
output += "</li>";
|
||||
});
|
||||
|
||||
output += "</ol>"
|
||||
output += "</div>";
|
||||
}
|
||||
}
|
||||
|
||||
window.dialog({'html': "<div id='favorite-portal-list'>" + output + "</div>", 'title': 'Favorite portals', 'id': 'favorite-portals'});
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.onDelete = function(guid) {
|
||||
delete window.plugin.favoritePortals.portalList[ guid ];
|
||||
if(window.selectedPortal && window.selectedPortal === guid)
|
||||
$('.toggle-favorite-portal').removeClass( 'portal-on' ).addClass( 'portal-off' );
|
||||
$("li[name='" + guid + "']").remove();
|
||||
window.plugin.favoritePortals.savePortals();
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.onPortalClicked = function(guid, coords) {
|
||||
window.zoomToAndShowPortal(guid, coords);
|
||||
$('#dialog-favorite-portals').dialog('close');
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.togglePortal = function() {
|
||||
if(window.plugin.favoritePortals.portalList[window.selectedPortal]) {
|
||||
$('.toggle-favorite-portal').removeClass('portal-on').addClass('portal-off');
|
||||
delete window.plugin.favoritePortals.portalList[ window.selectedPortal ];
|
||||
} else {
|
||||
$('.toggle-favorite-portal').removeClass('portal-off').addClass('portal-on');
|
||||
window.plugin.favoritePortals.portalList[window.selectedPortal] = window.portals[window.selectedPortal].options;
|
||||
}
|
||||
window.plugin.favoritePortals.savePortals();
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.savePortals = function() {
|
||||
var portalsObject = {'portals': window.plugin.favoritePortals.portalList};
|
||||
var portalListJSON = JSON.stringify(portalsObject);
|
||||
localStorage[window.plugin.favoritePortals.LOCAL_STORAGE_KEY] = portalListJSON;
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.loadPortals = function() {
|
||||
var portalListJSON = localStorage[window.plugin.favoritePortals.LOCAL_STORAGE_KEY];
|
||||
if(!portalListJSON) return;
|
||||
var portalsObject = JSON.parse(portalListJSON);
|
||||
window.plugin.favoritePortals.portalList = portalsObject.portals;
|
||||
}
|
||||
|
||||
window.plugin.favoritePortals.setup = function() {
|
||||
window.plugin.favoritePortals.loadPortals();
|
||||
window.addHook('portalDetailsUpdated', window.plugin.favoritePortals.onDetailsUpdated);
|
||||
$('#toolbox').append("<a onclick='window.plugin.favoritePortals.display()' title='Create a list of favorite portals'>Favorite Portals</a>");
|
||||
$("<style>").prop("type", "text/css").html(".toggle-favorite-portal {\
|
||||
width: 13px;\
|
||||
height: 13px;\
|
||||
margin-left: 10px;\
|
||||
vertical-align: middle;\
|
||||
display: inline-block;\
|
||||
cursor: pointer;\
|
||||
border: 1px solid #20A8B1;\
|
||||
}\
|
||||
.portal-on {\
|
||||
background-color: #20A8B1;\
|
||||
}\
|
||||
.portal-off {\
|
||||
}\
|
||||
.linkdetails {\
|
||||
margin-bottom: 5px;\
|
||||
}\
|
||||
.delete-favorite-portal {\
|
||||
width: 10px;\
|
||||
height: 10px;\
|
||||
color: #FFCC00;\
|
||||
border: 2px solid #20A8B1;\
|
||||
margin-right: 10px;\
|
||||
padding-left: 3px;\
|
||||
padding-right: 3px;\
|
||||
font-weight: bolder;\
|
||||
}\
|
||||
#favorite-portal-list {\
|
||||
padding: 5px;\
|
||||
}\
|
||||
#favorite-portal-list li {\
|
||||
line-height: 1.8;\
|
||||
}").appendTo("head");
|
||||
};
|
||||
|
||||
var setup = window.plugin.favoritePortals.setup;
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-guess-player-levels@breunigs
|
||||
// @name IITC plugin: guess player level
|
||||
// @category Info
|
||||
// @version 0.4.9.@@DATETIMEVERSION@@
|
||||
// @version 0.5.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -21,35 +21,81 @@
|
||||
// use own namespace for plugin
|
||||
window.plugin.guessPlayerLevels = function() {};
|
||||
|
||||
// we prepend a hash sign (#) in front of the player name in storage in order to prevent accessing a pre-defined property
|
||||
// (like constructor, __defineGetter__, etc.
|
||||
|
||||
window.plugin.guessPlayerLevels.setupCallback = function() {
|
||||
$('#toolbox').append(' <a onclick="window.plugin.guessPlayerLevels.guess()" title="Show player level guesses based on resonator placement in displayed portals">Guess player levels</a>');
|
||||
addHook('portalAdded', window.plugin.guessPlayerLevels.extractPortalData);
|
||||
addHook('portalDetailLoaded', window.plugin.guessPlayerLevels.extractPortalData);
|
||||
addHook('publicChatDataAvailable', window.plugin.guessPlayerLevels.extractChatData);
|
||||
}
|
||||
|
||||
|
||||
// This function is intended to be called by other plugins
|
||||
window.plugin.guessPlayerLevels.fetchLevelByPlayer = function(guid) {
|
||||
return(window.localStorage['level-' + guid]);
|
||||
window.plugin.guessPlayerLevels.fetchLevelByPlayer = function(nick) {
|
||||
var cache = window.plugin.guessPlayerLevels._nameToLevelCache;
|
||||
|
||||
if(cache['#' + nick] === undefined)
|
||||
cache = window.plugin.guessPlayerLevels._loadLevels();
|
||||
|
||||
var details = cache['#' + nick];
|
||||
if(details === undefined)
|
||||
return 1;
|
||||
if(typeof details === 'number')
|
||||
return details;
|
||||
return details.guessed;
|
||||
}
|
||||
|
||||
window.plugin.guessPlayerLevels._nameToGuidCache = {};
|
||||
// This function is intended to be called by other plugins
|
||||
window.plugin.guessPlayerLevels.fetchLevelDetailsByPlayer = function(nick) {
|
||||
var cache = window.plugin.guessPlayerLevels._nameToLevelCache;
|
||||
|
||||
if(cache['#' + nick] === undefined)
|
||||
cache = window.plugin.guessPlayerLevels._loadLevels();
|
||||
|
||||
var details = cache['#' + nick];
|
||||
if(details === undefined)
|
||||
return {min: 1, guessed: 1};
|
||||
if(typeof details === 'number')
|
||||
return {min: 1, guessed: details};
|
||||
return details;
|
||||
}
|
||||
|
||||
window.plugin.guessPlayerLevels._nameToLevelCache = {};
|
||||
window.plugin.guessPlayerLevels._localStorageLastUpdate = 0;
|
||||
|
||||
window.plugin.guessPlayerLevels._loadLevels = function() {
|
||||
// no use in reading localStorage repeatedly
|
||||
if(window.plugin.guessPlayerLevels._localStorageLastUpdate < Date.now() - 10*1000) {
|
||||
try {
|
||||
var cache = JSON.parse(localStorage['plugin-guess-player-levels'])
|
||||
window.plugin.guessPlayerLevels._nameToLevelCache = cache;
|
||||
window.plugin.guessPlayerLevels._localStorageLastUpdate = Date.now();
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
|
||||
return window.plugin.guessPlayerLevels._nameToLevelCache;
|
||||
}
|
||||
|
||||
window.plugin.guessPlayerLevels.setLevelTitle = function(dom) {
|
||||
// expects dom node with nick in its child text node
|
||||
|
||||
var el = $(dom);
|
||||
var nick = el.text();
|
||||
var guid = window.playerNameToGuid(nick);
|
||||
var level = guid ? localStorage['level-'+guid] : null;
|
||||
|
||||
var details = window.plugin.guessPlayerLevels.fetchLevelDetailsByPlayer(nick);
|
||||
|
||||
var text;
|
||||
if (level) {
|
||||
text = 'Min player level: ' + level + ' (guessed)';
|
||||
} else {
|
||||
text = 'Min player level unknown';
|
||||
if(details.min == 8)
|
||||
text = 'Player level: 8';
|
||||
else {
|
||||
text = 'Min player level: ' + details.min;
|
||||
if(details.min != details.guessed)
|
||||
text += '\nGuessed player level: ' + details.guessed;
|
||||
}
|
||||
window.setupTooltips(el);
|
||||
|
||||
|
||||
/*
|
||||
This code looks hacky but since we are a little late within the mouseenter so
|
||||
we need to improvise a little. The open method doesn't open the tooltip directly.
|
||||
@ -63,13 +109,15 @@ window.plugin.guessPlayerLevels.setLevelTitle = function(dom) {
|
||||
}
|
||||
|
||||
window.plugin.guessPlayerLevels.setupChatNickHelper = function() {
|
||||
$(document).on('mouseenter', '.nickname', function() {
|
||||
$(document).on('mouseenter', '.nickname, .pl_nudge_player', function() {
|
||||
window.plugin.guessPlayerLevels.setLevelTitle(this);
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.guessPlayerLevels.extractPortalData = function(data) {
|
||||
var r = data.portal.options.details.resonatorArray.resonators;
|
||||
if(!data.success) return;
|
||||
|
||||
var r = data.details.resonatorArray.resonators;
|
||||
|
||||
//due to the Jarvis Virus/ADA Refactor it's possible for a player to own resonators on a portal
|
||||
//at a higher level than the player themselves. It is not possible to detect for sure when this
|
||||
@ -96,29 +144,98 @@ window.plugin.guessPlayerLevels.extractPortalData = function(data) {
|
||||
|
||||
$.each(perPlayerResMaxLevel, function(guid, level) {
|
||||
if (perPlayerResMaxLevelCount[guid] <= window.MAX_RESO_PER_PLAYER[level]) {
|
||||
var p = 'level-'+guid;
|
||||
if(!window.localStorage[p] || window.localStorage[p] < level)
|
||||
window.localStorage[p] = level;
|
||||
window.plugin.guessPlayerLevels.savePlayerLevel(guid, level);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.plugin.guessPlayerLevels.extractChatData = function(data) {
|
||||
data.raw.result.forEach(function(msg) {
|
||||
var plext = msg[2].plext;
|
||||
if(plext.plextType == 'SYSTEM_BROADCAST'
|
||||
&& plext.markup.length==5
|
||||
&& plext.markup[0][0] == 'PLAYER'
|
||||
&& plext.markup[1][0] == 'TEXT'
|
||||
&& plext.markup[1][1].plain == ' deployed an '
|
||||
&& plext.markup[2][0] == 'TEXT'
|
||||
&& plext.markup[2][0] == 'TEXT'
|
||||
&& plext.markup[3][0] == 'TEXT'
|
||||
&& plext.markup[3][1].plain == ' Resonator on ') {
|
||||
var nick = plext.markup[0][1].plain;
|
||||
var lvl = parseInt(plext.markup[2][1].plain.substr(1));
|
||||
window.plugin.guessPlayerLevels.savePlayerLevel(nick, lvl, true);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.plugin.guessPlayerLevels.savePlayerLevel = function(nick, level, safe) {
|
||||
var cache = window.plugin.guessPlayerLevels._loadLevels();
|
||||
|
||||
var details = cache['#' + nick];
|
||||
if(details === undefined)
|
||||
details = {min: 1, guessed: 1};
|
||||
if(typeof details === 'number')
|
||||
details = {min: 1, guessed: details};
|
||||
|
||||
if(safe) {
|
||||
if(details.min >= level)
|
||||
return;
|
||||
|
||||
details.min = level;
|
||||
if(details.guessed < details.min)
|
||||
details.guessed = details.min;
|
||||
} else {
|
||||
if(details.guessed >= level)
|
||||
return;
|
||||
|
||||
details.guessed = level;
|
||||
}
|
||||
|
||||
window.plugin.guessPlayerLevels._nameToLevelCache['#' + nick] = details;
|
||||
|
||||
// to minimize accesses to localStorage, writing is delayed a bit
|
||||
|
||||
if(window.plugin.guessPlayerLevels._writeTimeout)
|
||||
clearTimeout(window.plugin.guessPlayerLevels._writeTimeout);
|
||||
|
||||
window.plugin.guessPlayerLevels._writeTimeout = setTimeout(function() {
|
||||
localStorage['plugin-guess-player-levels'] = JSON.stringify(window.plugin.guessPlayerLevels._nameToLevelCache);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
window.plugin.guessPlayerLevels.guess = function() {
|
||||
var playersRes = {};
|
||||
var playersEnl = {};
|
||||
$.each(window.portals, function(ind, portal) {
|
||||
var r = portal.options.details.resonatorArray.resonators;
|
||||
$.each(r, function(ind, reso) {
|
||||
if(!reso) return true;
|
||||
if(isSystemPlayer(reso.ownerGuid)) return true;
|
||||
$.each(window.portals, function(guid,p) {
|
||||
var details = portalDetail.get(guid);
|
||||
if(details) {
|
||||
var r = details.resonatorArray.resonators;
|
||||
$.each(r, function(ind, reso) {
|
||||
if(!reso) return true;
|
||||
var nick = reso.ownerGuid;
|
||||
if(isSystemPlayer(nick)) return true;
|
||||
|
||||
var lvl = localStorage['level-' + reso.ownerGuid];
|
||||
var nick = getPlayerName(reso.ownerGuid);
|
||||
if(portal.options.team === TEAM_ENL)
|
||||
playersEnl[nick] = lvl;
|
||||
else
|
||||
playersRes[nick] = lvl;
|
||||
});
|
||||
var lvl = window.plugin.guessPlayerLevels.fetchLevelDetailsByPlayer(nick).min;
|
||||
if(!lvl) return true;
|
||||
|
||||
if(getTeam(details) === TEAM_ENL)
|
||||
playersEnl[nick] = lvl;
|
||||
else
|
||||
playersRes[nick] = lvl;
|
||||
});
|
||||
|
||||
if(details.captured) {
|
||||
var nick = details.captured.capturingPlayerId
|
||||
if(isSystemPlayer(nick)) return true;
|
||||
var lvl = window.plugin.guessPlayerLevels.fetchLevelDetailsByPlayer(nick).min;
|
||||
if(!lvl) return true;
|
||||
|
||||
if(getTeam(details) === TEAM_ENL)
|
||||
playersEnl[nick] = lvl;
|
||||
else
|
||||
playersRes[nick] = lvl;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var s = 'Players have at least the following level:\n\n';
|
||||
@ -129,18 +246,30 @@ window.plugin.guessPlayerLevels.guess = function() {
|
||||
var totallvlR = 0;
|
||||
var totallvlE = 0;
|
||||
var max = Math.max(namesR.length, namesE.length);
|
||||
for(var i = 0; i < max; i++) {
|
||||
var nickR = namesR[i];
|
||||
var lvlR = playersRes[nickR];
|
||||
var lineR = nickR ? nickR + ':\t' + lvlR : '\t';
|
||||
if(!isNaN(parseInt(lvlR)))
|
||||
totallvlR += parseInt(lvlR);
|
||||
|
||||
var nickE = namesE[i];
|
||||
var lvlE = playersEnl[nickE];
|
||||
var lineE = nickE ? nickE + ':\t' + lvlE : '\t';
|
||||
if(!isNaN(parseInt(lvlE)))
|
||||
totallvlE += parseInt(lvlE);
|
||||
function makeRow(nick, lvl, team) {
|
||||
if(!nick)
|
||||
return '\t';
|
||||
|
||||
var color = COLORS[team];
|
||||
if (nick === window.PLAYER.nickname) color = '#fd6'; //highlight the player's name in a unique colour (similar to @player mentions from others in the chat text itself)
|
||||
|
||||
return '<mark class="nickname" style="color:'+color+'">'+nick+'</mark>\t' + lvl;
|
||||
}
|
||||
|
||||
var nick, lvl, lineE, lineR;
|
||||
for(var i = 0; i < max; i++) {
|
||||
nick = namesR[i];
|
||||
lvl = playersRes[nick];
|
||||
lineR = makeRow(nick, lvl, TEAM_RES);
|
||||
if(!isNaN(parseInt(lvl)))
|
||||
totallvlR += parseInt(lvl);
|
||||
|
||||
nick = namesE[i];
|
||||
lvl = playersEnl[nick];
|
||||
lineE = makeRow(nick, lvl, TEAM_ENL);
|
||||
if(!isNaN(parseInt(lvl)))
|
||||
totallvlE += parseInt(lvl);
|
||||
|
||||
s += '\n'+lineR + '\t' + lineE + '\n';
|
||||
}
|
||||
@ -150,8 +279,8 @@ window.plugin.guessPlayerLevels.guess = function() {
|
||||
if (namesR.length > 0) averageR = (totallvlR/namesR.length);
|
||||
if (namesE.length > 0) averageE = (totallvlE/namesE.length);
|
||||
s += '\nAverage level:\t'+averageR.toFixed(2)+'\tAverage level:\t'+averageE.toFixed(2);
|
||||
s += '\n\nIf there are some unresolved names, simply try again.'
|
||||
//console.log(s);
|
||||
s += '\n\nOnly players from recently viewed portal details are listed.'
|
||||
|
||||
dialog({
|
||||
text: s,
|
||||
title: 'Player levels: R' + averageR.toFixed(2) + ', E' + averageE.toFixed(2),
|
||||
@ -160,24 +289,19 @@ window.plugin.guessPlayerLevels.guess = function() {
|
||||
buttons: {
|
||||
'RESET GUESSES': function() {
|
||||
// clear all guessed levels from local storage
|
||||
$.each(Object.keys(localStorage), function(ind,key) {
|
||||
if(key.lastIndexOf("level-",0)===0) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
});
|
||||
localStorage.removeItem('plugin-guess-player-levels')
|
||||
window.plugin.guessPlayerLevels._nameToLevelCache = {}
|
||||
// now force all portals through the callback manually
|
||||
$.each(window.portals, function(guid,p) {
|
||||
window.plugin.guessPlayerLevels.extractPortalData({portal: p});
|
||||
var details = portalDetail.get(guid);
|
||||
if(details)
|
||||
window.plugin.guessPlayerLevels.extractPortalData({details:details, success:true});
|
||||
});
|
||||
// and re-open the dialog (on a minimal timeout - so it's not closed while processing this callback)
|
||||
setTimeout(window.plugin.guessPlayerLevels.guess,1);
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//run the name resolving process
|
||||
resolvePlayerNames();
|
||||
}
|
||||
|
||||
window.plugin.guessPlayerLevels.sort = function(playerHash) {
|
||||
@ -193,6 +317,14 @@ window.plugin.guessPlayerLevels.sort = function(playerHash) {
|
||||
|
||||
|
||||
var setup = function() {
|
||||
// we used to sture level guesses as one localStorage key per player, named 'level-PLAYER_GUID'
|
||||
// they're now stored in a single storage key - 'plugin-guess-player-levels' - so clear these old entries
|
||||
$.each(Object.keys(localStorage), function(ind,key) {// legacy code - should be removed in the future
|
||||
if(key.lastIndexOf('level-',0)===0) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
});
|
||||
|
||||
window.plugin.guessPlayerLevels.setupCallback();
|
||||
window.plugin.guessPlayerLevels.setupChatNickHelper();
|
||||
}
|
||||
|
@ -1,111 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-ipas-link@graphracer
|
||||
// @name IITC Plugin: simulate an attack on portal
|
||||
// @category Portal Info
|
||||
// @category Deleted
|
||||
// @version 0.2.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/xosofox/IPAS
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Adds a link to the portal details to open the portal in IPAS - Ingress Portal Attack Simulator on http://ipas.graphracer.com
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.ipasLink = function() {};
|
||||
|
||||
window.plugin.ipasLink.setupCallback = function() {
|
||||
addHook('portalDetailsUpdated', window.plugin.ipasLink.addLink);
|
||||
}
|
||||
|
||||
window.plugin.ipasLink.addLink = function(d) {
|
||||
$('.linkdetails').append('<aside><a href="http://ipas.graphracer.com/index.html#' + window.plugin.ipasLink.getHash(d.portalDetails) + '" target="ipaswindow" title="Use IPAS to simulate an attack on this portal">Simulate attack</a></aside>');
|
||||
}
|
||||
|
||||
window.plugin.ipasLink.getHash = function (d) {
|
||||
var hashParts = [];
|
||||
$.each(d.resonatorArray.resonators, function (ind, reso) {
|
||||
if (reso) {
|
||||
hashParts.push(reso.level + "," + reso.distanceToPortal + "," + reso.energyTotal);
|
||||
} else {
|
||||
hashParts.push("1,20,0");
|
||||
}
|
||||
});
|
||||
var resos = hashParts.join(";");
|
||||
|
||||
hashParts = [];
|
||||
$.each(d.portalV2.linkedModArray, function (ind, mod) {
|
||||
// s - shields
|
||||
// h - heat sink
|
||||
// i - intentionally left in
|
||||
// t - turret
|
||||
//
|
||||
// f - force amp
|
||||
// m - multi-hack
|
||||
// l - link-amp
|
||||
//
|
||||
var modCodes = {
|
||||
"RES_SHIELD": "s",
|
||||
"HEATSINK": "h",
|
||||
"TURRET": "t",
|
||||
"FORCE_AMP": "f",
|
||||
"MULTIHACK": "m",
|
||||
"LINK_AMPLIFIER": "l"
|
||||
}
|
||||
|
||||
var mc = "0";
|
||||
if (mod) {
|
||||
if (mod.type in modCodes) {
|
||||
mc = modCodes[mod.type] + mod.rarity.charAt(0).toLowerCase();
|
||||
|
||||
//special for shields to distinguish old/new mitigation
|
||||
if (mod.type == "RES_SHIELD") {
|
||||
mc += mod.stats.MITIGATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
hashParts.push(mc);
|
||||
});
|
||||
var shields = hashParts.join(",");
|
||||
|
||||
var linkParts = [];
|
||||
var edges = d.portalV2.linkedEdges;
|
||||
|
||||
var portalL = new L.LatLng(d.locationE6.latE6 / 1E6, d.locationE6.lngE6 / 1E6)
|
||||
$.each(edges, function (ind, edge) {
|
||||
//calc distance in m here
|
||||
var distance = 1; //default to 1m, so a low level portal would support it
|
||||
|
||||
//Try to find other portals details
|
||||
var guid = edge.otherPortalGuid
|
||||
if (window.portals[guid] !== undefined) {
|
||||
//get other portals details as o
|
||||
var o = window.portals[guid].options.details;
|
||||
var otherPortalL = new L.LatLng(o.locationE6.latE6 / 1E6, o.locationE6.lngE6 / 1E6);
|
||||
var distance = Math.round(portalL.distanceTo(otherPortalL));
|
||||
}
|
||||
|
||||
if (!(edge.isOrigin)) {
|
||||
distance = distance * -1;
|
||||
}
|
||||
linkParts.push(distance);
|
||||
});
|
||||
var links = linkParts.join(",");
|
||||
|
||||
return resos + "/" + shields + "/" + links; //changed with IPAS 1.1 to / instead of |
|
||||
}
|
||||
|
||||
var setup = function () {
|
||||
window.plugin.ipasLink.setupCallback();
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-farms@949
|
||||
// @name IITC plugin: Show farms by level
|
||||
// @category Info
|
||||
// @version 1.4.0.@@DATETIMEVERSION@@
|
||||
// @version 1.4.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -62,7 +62,7 @@ window.plugin.farmFind.getNearbyPortalCount = function(portal){
|
||||
$.each(window.portals, function(i, otherPortal) {
|
||||
var thisPortal = new google.maps.LatLng(otherPortal.getLatLng().lat, otherPortal.getLatLng().lng);
|
||||
if (circle.getBounds().contains(thisPortal))
|
||||
if (getPortalLevel(otherPortal.options.details) >= window.plugin.farmFind.minLevel) nearby8Portals++;
|
||||
if (otherPortal.options.level >= window.plugin.farmFind.minLevel) nearby8Portals++;
|
||||
});
|
||||
//console.log(nearby8Portals);
|
||||
return nearby8Portals;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id max-links@boombuler
|
||||
// @name IITC plugin: Max Links
|
||||
// @category Layer
|
||||
// @version 0.4.1.@@DATETIMEVERSION@@
|
||||
// @version 0.4.2.@@DATETIMEVERSION@@
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Calculates how to link the portals to create a reasonably tidy set of links/fields. Enable from the layer chooser. (Max Links is a poor name, but remains for historical reasons.)
|
||||
@ -22,27 +22,21 @@ window.plugin.maxLinks = function() {};
|
||||
|
||||
// const values
|
||||
window.plugin.maxLinks.MAX_PORTALS_TO_LINK = 200;
|
||||
// zoom level used for projecting points between latLng and pixel coordinates. may affect precision of triangulation
|
||||
window.plugin.maxLinks.PROJECT_ZOOM = 16;
|
||||
|
||||
window.plugin.maxLinks.STROKE_STYLE = {
|
||||
color: '#FF0000',
|
||||
opacity: 1,
|
||||
weight: 2,
|
||||
weight: 1.5,
|
||||
clickable: false,
|
||||
dashArray: [8,6],
|
||||
dashArray: [6,4],
|
||||
smoothFactor: 10,
|
||||
};
|
||||
window.plugin.maxLinks.layer = null;
|
||||
window.plugin.maxLinks.errorMarker = null;
|
||||
|
||||
|
||||
window.plugin.maxLinks.Point = function(x,y) {
|
||||
this.x=x;
|
||||
this.y=y;
|
||||
}
|
||||
window.plugin.maxLinks.Point.prototype.toString = function() {
|
||||
return this.x+","+this.y;
|
||||
}
|
||||
|
||||
|
||||
window.plugin.maxLinks.addErrorMarker = function() {
|
||||
if (window.plugin.maxLinks.errorMarker == null) {
|
||||
@ -81,10 +75,13 @@ window.plugin.maxLinks.updateLayer = function() {
|
||||
|
||||
var locations = [];
|
||||
|
||||
var bounds = map.getBounds();
|
||||
$.each(window.portals, function(guid, portal) {
|
||||
var loc = portal.options.details.locationE6;
|
||||
var nloc = new window.plugin.maxLinks.Point(loc.latE6/1E6, loc.lngE6/1E6);
|
||||
locations.push(nloc);
|
||||
var ll = portal.getLatLng();
|
||||
if (bounds.contains(ll)) {
|
||||
var p = map.project (portal.getLatLng(), window.plugin.maxLinks.PROJECT_ZOOM);
|
||||
locations.push(p);
|
||||
}
|
||||
});
|
||||
|
||||
var triangles = window.delaunay.triangulate(locations);
|
||||
@ -117,7 +114,11 @@ window.plugin.maxLinks.updateLayer = function() {
|
||||
//using drawnLinks[a] as a set - so the stored value is of no importance
|
||||
drawnLinks[a][b] = null;
|
||||
|
||||
var poly = L.polyline([[a.x,a.y],[b.x,b.y]], window.plugin.maxLinks.STROKE_STYLE);
|
||||
// convert back from x/y coordinates to lat/lng for drawing
|
||||
var alatlng = map.unproject (a, window.plugin.maxLinks.PROJECT_ZOOM);
|
||||
var blatlng = map.unproject (b, window.plugin.maxLinks.PROJECT_ZOOM);
|
||||
|
||||
var poly = L.polyline([alatlng, blatlng], window.plugin.maxLinks.STROKE_STYLE);
|
||||
poly.addTo(window.plugin.maxLinks.layer);
|
||||
drawnLinkCount++;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-player-tracker@breunigs
|
||||
// @name IITC Plugin: Player tracker
|
||||
// @category Layer
|
||||
// @version 0.10.0.@@DATETIMEVERSION@@
|
||||
// @version 0.10.2.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -165,7 +165,7 @@ window.plugin.playerTracker.processNewData = function(data) {
|
||||
}
|
||||
break;
|
||||
case 'PLAYER':
|
||||
pguid = markup[1].guid;
|
||||
pguid = markup[1].plain;
|
||||
break;
|
||||
case 'PORTAL':
|
||||
// link messages are “player linked X to Y” and the player is at
|
||||
@ -196,7 +196,7 @@ window.plugin.playerTracker.processNewData = function(data) {
|
||||
if(!playerData || playerData.events.length === 0) {
|
||||
plugin.playerTracker.stored[pguid] = {
|
||||
// this always resolves, as the chat delivers this data
|
||||
nick: window.getPlayerName(pguid),
|
||||
nick: pguid,
|
||||
team: json[2].plext.team,
|
||||
events: [newEvent]
|
||||
};
|
||||
@ -250,9 +250,9 @@ window.plugin.playerTracker.getLatLngFromEvent = function(ev) {
|
||||
//TODO? add weight to certain events, or otherwise prefer them, to give better locations?
|
||||
var lats = 0;
|
||||
var lngs = 0;
|
||||
$.each(ev.latlngs, function() {
|
||||
lats += this[0];
|
||||
lngs += this[1];
|
||||
$.each(ev.latlngs, function(i, latlng) {
|
||||
lats += latlng[0];
|
||||
lngs += latlng[1];
|
||||
});
|
||||
|
||||
return L.latLng(lats / ev.latlngs.length, lngs / ev.latlngs.length);
|
||||
@ -311,16 +311,22 @@ window.plugin.playerTracker.drawData = function() {
|
||||
var popup = '<span class="nickname '+cssClass+'" style="font-weight:bold;">' + playerData.nick + '</span>';
|
||||
|
||||
if(window.plugin.guessPlayerLevels !== undefined &&
|
||||
window.plugin.guessPlayerLevels.fetchLevelByPlayer !== undefined) {
|
||||
var playerLevel = window.plugin.guessPlayerLevels.fetchLevelByPlayer(pguid);
|
||||
if(playerLevel !== undefined) {
|
||||
popup += '<span style="font-weight:bold;margin-left:10px;">Level '
|
||||
+ playerLevel
|
||||
+ ' (guessed)'
|
||||
+ '</span>';
|
||||
} else {
|
||||
popup += '<span style="font-weight:bold;margin-left:10px;">Level unknown</span>'
|
||||
window.plugin.guessPlayerLevels.fetchLevelDetailsByPlayer !== undefined) {
|
||||
function getLevel(lvl) {
|
||||
return '<span style="padding:4px;color:white;background-color:'+COLORS_LVL[lvl]+'">'+lvl+'</span>';
|
||||
}
|
||||
popup += '<span style="font-weight:bold;margin-left:10px;">';
|
||||
|
||||
var playerLevelDetails = window.plugin.guessPlayerLevels.fetchLevelDetailsByPlayer(pguid);
|
||||
if(playerLevelDetails.min == 8) {
|
||||
popup += 'Level ' + getLevel(8);
|
||||
} else {
|
||||
popup += 'Min level: ' + getLevel(playerLevelDetails.min);
|
||||
if(playerLevelDetails.min != playerLevelDetails.guessed)
|
||||
popup += ', guessed level: ' + getLevel(playerLevelDetails.guessed);
|
||||
}
|
||||
|
||||
popup += '</span>';
|
||||
}
|
||||
|
||||
popup += '<br>'
|
||||
@ -344,15 +350,15 @@ window.plugin.playerTracker.drawData = function() {
|
||||
var eventPortal = []
|
||||
var closestPortal;
|
||||
var mostPortals = 0;
|
||||
$.each(last.guids, function() {
|
||||
if(eventPortal[this]) {
|
||||
eventPortal[this]++;
|
||||
$.each(last.guids, function(i, guid) {
|
||||
if(eventPortal[guid]) {
|
||||
eventPortal[guid]++;
|
||||
} else {
|
||||
eventPortal[this] = 1;
|
||||
eventPortal[guid] = 1;
|
||||
}
|
||||
if(eventPortal[this] > mostPortals) {
|
||||
mostPortals = eventPortal[this];
|
||||
closestPortal = this;
|
||||
if(eventPortal[guid] > mostPortals) {
|
||||
mostPortals = eventPortal[guid];
|
||||
closestPortal = guid;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,107 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-players-resonators@rbino
|
||||
// @name IITC plugin: Player's Resonators
|
||||
// @category Deleted
|
||||
// @version 0.1.5.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] The plugins finds the resonators of a given player. The input is in the sidebar.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
/*********************************************************************************************************
|
||||
* Changelog:
|
||||
*
|
||||
* 0.1.5 Added portal and reso counter and reso details (Thanks BJT)
|
||||
* 0.1.4 Added focus link in the toolbox. Some renaming. Removed div to use sidebar style.
|
||||
* 0.1.3 Effective player name (with wrong capitalization) if it finds some reso
|
||||
* 0.1.2 Made nickname case insensitive
|
||||
* 0.1.1 Added mouseover for portal location. Dirty hack to not show mousehover when the alert is fired.
|
||||
* 0.1.0 First public release
|
||||
*********************************************************************************************************/
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.playersResonators = function() {};
|
||||
|
||||
window.plugin.playersResonators.findReso = function(playername) {
|
||||
var s = "";
|
||||
var portalSet = {};
|
||||
var effectiveNick = "";
|
||||
var portalCounter = 0;
|
||||
var resoCounter = 0;
|
||||
// Assuming there can be no agents with same nick with different lower/uppercase
|
||||
var nickToFind = playername.toLowerCase();
|
||||
$.each(window.portals, function(ind, portal){
|
||||
var resoLevels = {};
|
||||
var r = portal.options.details.resonatorArray.resonators;
|
||||
$.each(r, function(ind, reso) {
|
||||
if (!reso) return true;
|
||||
var nick = getPlayerName(reso.ownerGuid);
|
||||
if (nick.toLowerCase() === nickToFind){
|
||||
resoCounter += 1;
|
||||
if (!effectiveNick) {
|
||||
effectiveNick = nick;
|
||||
}
|
||||
if (reso.level in resoLevels){
|
||||
resoLevels[reso.level] += 1;
|
||||
} else {
|
||||
resoLevels[reso.level] = 1;
|
||||
}
|
||||
if (!portalSet.hasOwnProperty(portal.options.guid)){
|
||||
portalSet[portal.options.guid] = true;
|
||||
var latlng = [portal.options.details.locationE6.latE6/1E6, portal.options.details.locationE6.lngE6/1E6].join();
|
||||
var guid = portal.options.guid;
|
||||
var zoomPortal = 'window.zoomToAndShowPortal(\''+guid+'\', ['+latlng+']);return false';
|
||||
var perma = '/intel?latE6='+portal.options.details.locationE6.latE6+'&lngE6='+portal.options.details.locationE6.lngE6+'&z=17&pguid='+guid;
|
||||
var a = $('<a>',{
|
||||
"class": 'help',
|
||||
text: portal.options.details.portalV2.descriptiveText.TITLE,
|
||||
title: portal.options.details.portalV2.descriptiveText.ADDRESS,
|
||||
href: perma,
|
||||
onClick: zoomPortal
|
||||
})[0].outerHTML;
|
||||
portalCounter += 1;
|
||||
s += a + ": ";
|
||||
}
|
||||
}
|
||||
});
|
||||
if (portalSet.hasOwnProperty(portal.options.guid)){
|
||||
for (var i = 8; i>0; i--){
|
||||
if (i in resoLevels)
|
||||
s += resoLevels[i] + "xL" + i + " ";
|
||||
}
|
||||
s += "\n";
|
||||
}
|
||||
});
|
||||
if (s) {
|
||||
// Showing the playername as a "fake" link to avoid the auto-mouseover effect on the first portal
|
||||
fakeLinkPlayer = '<a href="#" onClick="return false;">' + effectiveNick + '</a>'
|
||||
s = fakeLinkPlayer + " has " + resoCounter + " resonators on " + portalCounter + " portals:\n\n" + s;
|
||||
} else {
|
||||
s = playername + " has no resonators in this range\n";
|
||||
}
|
||||
alert(s);
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
var content = '<input id="playerReso" placeholder="Type player name to find resonators..." type="text">';
|
||||
$('#sidebar').append(content);
|
||||
$('#toolbox').append(' <a onclick=$("#playerReso").focus() title="Find all portals with resonators of a certain player">Player\'s Reso</a>');
|
||||
$("#playerReso").keypress(function(e) {
|
||||
if((e.keyCode ? e.keyCode : e.which) !== 13) return;
|
||||
var data = $(this).val();
|
||||
window.plugin.playersResonators.findReso(data);
|
||||
});
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-portals-count@yenky
|
||||
// @name IITC plugin: Show total counts of portals
|
||||
// @category Info
|
||||
// @version 0.0.8.@@DATETIMEVERSION@@
|
||||
// @version 0.0.9.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -50,9 +50,8 @@ window.plugin.portalcounts.getPortals = function(){
|
||||
|
||||
$.each(window.portals, function(i, portal) {
|
||||
retval=true;
|
||||
var d = portal.options.details;
|
||||
var level = portal.options.level;
|
||||
var team = portal.options.team;
|
||||
var level = Math.floor(getPortalLevel(d));
|
||||
// just count portals in viewport
|
||||
if(!displayBounds.contains(portal.getLatLng())) return true;
|
||||
switch (team){
|
||||
@ -84,15 +83,16 @@ window.plugin.portalcounts.getPortals = function(){
|
||||
counts += '<td class="enl">'+window.plugin.portalcounts.PortalsEnl[level]+'</td><td class="res">'+window.plugin.portalcounts.PortalsRes[level]+'</td>';
|
||||
counts += '</tr>';
|
||||
}
|
||||
counts += '<tr><td colspan="3"> </td></tr>';
|
||||
|
||||
counts += '<tr><th>Total:</th><td class="enl">'+window.plugin.portalcounts.enlP+'</td><td class="res">'+window.plugin.portalcounts.resP+'</td></tr>';
|
||||
|
||||
counts += '<tr><td>Neutral:</td><td colspan="2">';
|
||||
if(minlvl > 0)
|
||||
counts += 'zoom in to see unclaimed';
|
||||
counts += 'zoom in to see unclaimed portals';
|
||||
else
|
||||
counts += window.plugin.portalcounts.neuP;
|
||||
counts += ' Portal(s)</td></tr>';
|
||||
counts += '<tr class="enl"><th colspan="2">Enlightened:</th><td>'+window.plugin.portalcounts.enlP+' Portal(s)</td></tr>';
|
||||
counts += '<tr class="res"><th colspan="2">Resistance:</th><td>'+window.plugin.portalcounts.resP+' Portal(s)</td></tr>';
|
||||
counts += '</td></tr>';
|
||||
|
||||
} else
|
||||
counts += '<tr><td>No Portals in range!</td></tr>';
|
||||
counts += '</table>';
|
||||
|
@ -1,17 +1,18 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-defense@gluckies
|
||||
// @name IITC plugin: portal defense
|
||||
// @category Layer
|
||||
// @category Deleted
|
||||
// @version 0.2.2.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows the defense values of every portal (see also "hightlight portals total mitigation" highlighter)
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @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==
|
||||
<<<<<<< HEAD
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
@ -169,3 +170,5 @@ var setup = function() {
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
=======
|
||||
>>>>>>> 68ec278914ced792f20cbd133f9481d6078435a6
|
||||
|
@ -1,49 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-bad-deployment-distance@cathesaurus
|
||||
// @name IITC plugin: highlight badly-deployed portals
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to show the effective resonator deployment range, where that average is less than 36 metres
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighlighterBadDeploymentDistance = function() {};
|
||||
|
||||
window.plugin.portalHighlighterBadDeploymentDistance.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_deployment = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
var avgDist = window.getAvgResoDist(d);
|
||||
if(avgDist > 0 && avgDist < window.HACK_RANGE*0.9) {
|
||||
portal_deployment = (window.HACK_RANGE - avgDist)/window.HACK_RANGE;
|
||||
}
|
||||
if(portal_deployment > 0) {
|
||||
var fill_opacity = portal_deployment*.85 + .15;
|
||||
// magenta for *exceptionally* close deployments (spoofing? under 1m average), then shades of
|
||||
// red, orange and yellow for further out
|
||||
color = avgDist < 1 ? 'magenta' : avgDist < (window.HACK_RANGE*.25) ? 'red' : avgDist < (window.HACK_RANGE*.6) ? 'orange' : 'yellow';
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Bad Deployment Distance', window.plugin.portalHighlighterBadDeploymentDistance.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,74 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-upgrade@vita10gy
|
||||
// @name IITC plugin: highlight portals you can upgrade to a specific level
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to highlight portals you can upgrade to a specific level.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel.highlight = function(data,highlight_level) {
|
||||
var d = data.portal.options.details;
|
||||
var current_level = Math.floor(getPortalLevel(d));
|
||||
var potential_level = Math.floor(window.potentialPortalLevel(d));
|
||||
var opacity = .7;
|
||||
if( potential_level > current_level && potential_level === highlight_level) {
|
||||
color = 'red';
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
|
||||
//determines the level of poral a user can make all on their own
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel.playerCanSoloLevel = function(lvl) {
|
||||
var resonators_total = 0;
|
||||
var resonators_placed = 0;
|
||||
var resonator_level = PLAYER.level
|
||||
while(resonators_placed < 8) {
|
||||
for(var i = 0; i<MAX_RESO_PER_PLAYER[resonator_level]; i++) {
|
||||
if(resonators_placed < 8) {
|
||||
resonators_total += resonator_level;
|
||||
resonators_placed++;
|
||||
}
|
||||
}
|
||||
resonator_level--;
|
||||
}
|
||||
return(Math.floor(resonators_total/8));
|
||||
}
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel.getHighlighter = function(lvl) {
|
||||
return(function(data){
|
||||
window.plugin.portalHighligherPortalsCanMakeLevel.highlight(data,lvl);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var setup = function() {
|
||||
// This is the maximum level of a portal a user can be the "last piece of"
|
||||
// yes, even a level 1 can be the difference in bumping a portal up to level 7
|
||||
var max_can_complete = 7;
|
||||
if(PLAYER.level === 8) {
|
||||
max_can_complete = 8;
|
||||
}
|
||||
// The rational behind the "minimum" level below is that showing a level 7 player, for example, all the portals they can make
|
||||
// a level 5 would be silly, as they can make ANY portal a level 5.
|
||||
for(var ptl_lvl = window.plugin.portalHighligherPortalsCanMakeLevel.playerCanSoloLevel()+1; ptl_lvl<=max_can_complete; ptl_lvl++) {
|
||||
window.addPortalHighlighter('Can Make Level ' + ptl_lvl, window.plugin.portalHighligherPortalsCanMakeLevel.getHighlighter(ptl_lvl));
|
||||
}
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,64 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-imminent-decay@cathesaurus
|
||||
// @name IITC plugin: highlight portals with resonators about to decay
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to show resonators due to decay within the next day. Red = portal will decay completely, orange = portal will drop all links, yellow = one or more resonators will decay completely.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighlighterImminentDecay = function() {};
|
||||
|
||||
window.plugin.portalHighlighterImminentDecay.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
if(getTeam(d) !== 0) {
|
||||
//Check the energy of every resonator.
|
||||
var resImminentDecayCount = 0;
|
||||
var resCount = 0;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso !== null) {
|
||||
var level = parseInt(reso.level);
|
||||
var maxResonatorEnergy = window.RESO_NRG[level];
|
||||
var currentResonatorEnergy = parseInt(reso.energyTotal);
|
||||
if((currentResonatorEnergy / maxResonatorEnergy) < 0.15) {
|
||||
resImminentDecayCount++;
|
||||
}
|
||||
resCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if(resImminentDecayCount > 0) {
|
||||
if(resImminentDecayCount === resCount) {
|
||||
var color = 'red';
|
||||
} else if((resCount - resImminentDecayCount) < 3) {
|
||||
color = 'orange';
|
||||
} else {
|
||||
color = 'yellow';
|
||||
}
|
||||
// Apply colour to portal.
|
||||
var params = {fillColor: color, fillOpacity: 1};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
window.COLOR_SELECTED_PORTAL = '#f0f';
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Imminent Decay', window.plugin.portalHighlighterImminentDecay.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-highlight-portal-infrastructure@vita10gy
|
||||
// @name IITC plugin: highlight portals with infrastructure problems
|
||||
// @category Highlighter
|
||||
// @version 0.2.0.@@DATETIMEVERSION@@
|
||||
// @version 0.2.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -31,15 +31,15 @@ window.plugin.portalInfrastructure.badTitles = ['^statue$',
|
||||
'no title'];
|
||||
|
||||
window.plugin.portalInfrastructure.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var d = data.portal.options.data;
|
||||
var color = '';
|
||||
var opa = .75;
|
||||
|
||||
if(!(d.imageByUrl && d.imageByUrl.imageUrl)) {
|
||||
if(!(d.image)) {
|
||||
color = 'red';
|
||||
}
|
||||
|
||||
if((new RegExp(window.plugin.portalInfrastructure.badTitles.join("|"),'i')).test(d.portalV2.descriptiveText.TITLE)) {
|
||||
if((new RegExp(window.plugin.portalInfrastructure.badTitles.join("|"),'i')).test(d.title)) {
|
||||
color = color == 'red' ? 'orange' : 'yellow';
|
||||
opa = .9;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-highlight-portals-level-color@vita10gy
|
||||
// @name IITC plugin: highlight portals by level color
|
||||
// @category Highlighter
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @version 0.1.2.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -22,8 +22,7 @@
|
||||
window.plugin.portalHighligherPortalsLevelColor = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalsLevelColor.colorLevel = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_level = Math.floor(getPortalLevel(d));
|
||||
var portal_level = data.portal.options.data.level;
|
||||
var opacity = .6;
|
||||
data.portal.setStyle({fillColor: COLORS_LVL[portal_level], fillOpacity: opacity});
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-highlight-portals-missing-resonators@vita10gy
|
||||
// @name IITC plugin: highlight portals missing resonators
|
||||
// @category Highlighter
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @version 0.1.2.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -22,29 +22,19 @@
|
||||
window.plugin.portalsMissingResonators = function() {};
|
||||
|
||||
window.plugin.portalsMissingResonators.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_weakness = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
//Ding the portal for every missing resonator.
|
||||
var resCount = 0;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso === null) {
|
||||
portal_weakness += .125;
|
||||
} else {
|
||||
resCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if(portal_weakness > 0) {
|
||||
var fill_opacity = portal_weakness*.85 + .15;
|
||||
|
||||
if(data.portal.options.team != TEAM_NONE) {
|
||||
var res_count = data.portal.options.data.resCount;
|
||||
|
||||
if(res_count < 8) {
|
||||
var fill_opacity = ((8-res_count)/8)*.85 + .15;
|
||||
var color = 'red';
|
||||
fill_opacity = Math.round(fill_opacity*100)/100;
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
if(resCount < 8) {
|
||||
// Hole per missing resonator
|
||||
var dash = new Array(8-resCount + 1).join("1,4,") + "100,0"
|
||||
params["dashArray"] = dash;
|
||||
}
|
||||
|
||||
// Hole per missing resonator
|
||||
var dash = new Array((8 - res_count) + 1).join("1,4,") + "100,0"
|
||||
params.dashArray = dash;
|
||||
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-mitigation@jonatkins
|
||||
// @name IITC plugin: hightlight portals total mitigation
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to show mitigation. Shades of red to the maximum of 95, then tints towards purple for over 95
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherMitigation = function() {};
|
||||
|
||||
window.plugin.portalHighligherMitigation.highlight = function(data) {
|
||||
|
||||
var defense = window.getPortalMitigationDetails(data.portal.options.details);
|
||||
|
||||
if (defense.total > 0) {
|
||||
var fill_opacity = (defense.total/95)*.85 + .15;
|
||||
|
||||
var blue = Math.max(0,Math.min(255,Math.round(defense.excess/80*255)));
|
||||
|
||||
var colour = 'rgb(255,0,'+blue+')';
|
||||
|
||||
var params = {fillColor: colour, fillOpacity: fill_opacity};
|
||||
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Mitigation (defense)', window.plugin.portalHighligherMitigation.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,103 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-mods@vita10gy
|
||||
// @name IITC plugin: highlight portal mods
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote if the portal has the selected mod.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherMods = function() {};
|
||||
|
||||
window.plugin.portalHighligherMods.highlight = function(data, mod_type) {
|
||||
var d = data.portal.options.details;
|
||||
|
||||
if(!jQuery.isArray(mod_type)) {
|
||||
mod_type = [mod_type];
|
||||
}
|
||||
|
||||
var mod_effect = 0;
|
||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
||||
if(mod !== null && jQuery.inArray(mod.type, mod_type) > -1) {
|
||||
switch(mod.rarity){
|
||||
case 'COMMON':
|
||||
mod_effect++;
|
||||
break;
|
||||
case 'RARE':
|
||||
mod_effect+=2;
|
||||
break;
|
||||
case 'VERY_RARE':
|
||||
mod_effect+=3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(mod_effect > 0) {
|
||||
var fill_opacity = mod_effect/12*.8 + .2;
|
||||
var color = 'red';
|
||||
fill_opacity = Math.round(fill_opacity*100)/100;
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherMods.highlightNoMods = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
|
||||
var mods = 0;
|
||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
||||
if(mod !== null) {
|
||||
mods += 1;
|
||||
}
|
||||
});
|
||||
|
||||
if(mods == 0) {
|
||||
var fill_opacity = .6;
|
||||
var color = 'red';
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
} else if(mods <4) {
|
||||
var fill_opacity = .6;
|
||||
var color = 'yellow';
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.plugin.portalHighligherMods.getHighlighter = function(type) {
|
||||
return(function(data){
|
||||
window.plugin.portalHighligherMods.highlight(data,type);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var setup = function() {
|
||||
|
||||
$.each(MOD_TYPE, function(ind, name){
|
||||
window.addPortalHighlighter('Mod: '+name, window.plugin.portalHighligherMods.getHighlighter(ind));
|
||||
});
|
||||
|
||||
window.addPortalHighlighter('Mod: Hackability', window.plugin.portalHighligherMods.getHighlighter(['MULTIHACK', 'HEATSINK']));
|
||||
window.addPortalHighlighter('Mod: Attack', window.plugin.portalHighligherMods.getHighlighter(['FORCE_AMP', 'TURRET']));
|
||||
window.addPortalHighlighter('Mod: Defense', window.plugin.portalHighligherMods.getHighlighter(['RES_SHIELD', 'FORCE_AMP', 'TURRET']));
|
||||
window.addPortalHighlighter('Mod: None', window.plugin.portalHighligherMods.highlightNoMods);
|
||||
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,53 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-my-8-portals@vita10gy
|
||||
// @name IITC plugin: highlight my level 8's on portals
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote portals you have a level 8 on.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherMy8sOnPortals = function() {};
|
||||
|
||||
window.plugin.portalHighligherMy8sOnPortals.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_weakness = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
var color = 'red';
|
||||
var opacity = .7;
|
||||
|
||||
var resCount = false;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso !== null && reso.ownerGuid === PLAYER.guid && reso.level == 8) {
|
||||
resCount = true;
|
||||
}
|
||||
});
|
||||
|
||||
if(resCount) {
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
//Don't list it if it isn't applicable yet
|
||||
if(PLAYER.level == 8) {
|
||||
window.addPortalHighlighter('My Level 8 Resonators', window.plugin.portalHighligherMy8sOnPortals.highlight);
|
||||
}
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,70 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-my-portals@vita10gy
|
||||
// @name IITC plugin: highlight my portals
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote portals you have a hand in. Orange is just ownership. Yellow is shields. Red is Resonators. Red trumps both, yellow trumps orange.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherMyPortals = function() {};
|
||||
|
||||
window.plugin.portalHighligherMyPortals.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_weakness = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
var color = '';
|
||||
var opacity = .7;
|
||||
if(PLAYER.guid === d.captured.capturingPlayerId) {
|
||||
color = 'orange';
|
||||
}
|
||||
|
||||
var modCount = 0;
|
||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
||||
if(mod !== null && mod.installingUser === PLAYER.guid) {
|
||||
color = 'yellow';
|
||||
modCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if(modCount > 0) {
|
||||
opacity = modCount*.25*.7 + .3;
|
||||
}
|
||||
|
||||
var resCount = 0;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso !== null && reso.ownerGuid === PLAYER.guid) {
|
||||
color = 'red';
|
||||
resCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if(resCount > 0) {
|
||||
opacity = resCount*.125*.7 + .3;
|
||||
}
|
||||
|
||||
if(color !== '') {
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('My Portals', window.plugin.portalHighligherMyPortals.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -2,11 +2,11 @@
|
||||
// @id iitc-plugin-highlight-needs-recharge@vita10gy
|
||||
// @name IITC plugin: hightlight portals that need recharging
|
||||
// @category Highlighter
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote if the portal needs recharging
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote if the portal needs recharging. Colours also indicate severity: yellow: above 85%, orange: above 50%, red: above 15%, magenta: below 15%
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
@ -22,23 +22,23 @@
|
||||
window.plugin.portalHighligherNeedsRecharge = function() {};
|
||||
|
||||
window.plugin.portalHighligherNeedsRecharge.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_weakness = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
if(window.getTotalPortalEnergy(d) > 0 && window.getCurrentPortalEnergy(d) < window.getTotalPortalEnergy(d)) {
|
||||
portal_weakness = 1 - (window.getCurrentPortalEnergy(d)/window.getTotalPortalEnergy(d));
|
||||
}
|
||||
if(portal_weakness > 0) {
|
||||
var fill_opacity = portal_weakness*.85 + .15;
|
||||
color = 'red';
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
var d = data.portal.options.data;
|
||||
var portal_health = d.health/100;
|
||||
if(data.portal.options.team != TEAM_NONE && portal_health < 1) {
|
||||
var fill_opacity = (1-portal_health)*.85 + .15;
|
||||
var color;
|
||||
if (portal_health > .85) color = 'yellow';
|
||||
else if (portal_health > .5) color = 'orange';
|
||||
else if (portal_health > .15) color = 'red';
|
||||
else color = 'magenta';
|
||||
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Needs Recharge', window.plugin.portalHighligherNeedsRecharge.highlight);
|
||||
window.addPortalHighlighter('Needs Recharge (Health)', window.plugin.portalHighligherNeedsRecharge.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
@ -1,63 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-outbound-link-counter@cathesaurus
|
||||
// @name IITC plugin: highlight portals running low on outbound links
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to show the number of outbound links: red = 8 (i.e. no more outbound links may be made), orange = 6 or 7, yellow = 4 or 5.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighlighterOutboundLinkCounter = function() {};
|
||||
|
||||
window.plugin.portalHighlighterOutboundLinkCounter.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var outgoing = 0;
|
||||
var playerFaction = 0;
|
||||
|
||||
if (window.PLAYER.team === 'RESISTANCE') {
|
||||
playerFaction = window.TEAM_RES;
|
||||
} else {
|
||||
playerFaction = window.TEAM_ENL;
|
||||
}
|
||||
|
||||
// Only interested in portals of player's faction
|
||||
if(getTeam(d) === playerFaction) {
|
||||
if(d.portalV2.linkedEdges) $.each(d.portalV2.linkedEdges, function(ind, link) {
|
||||
if (link.isOrigin) {
|
||||
outgoing++;
|
||||
}
|
||||
});
|
||||
|
||||
if(outgoing > 3) {
|
||||
if(outgoing < 6) {
|
||||
color = 'yellow';
|
||||
} else if(outgoing < 8) {
|
||||
color = 'orange';
|
||||
} else {
|
||||
color = 'red';
|
||||
}
|
||||
var params = {fillColor: color, fillOpacity: 1};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Outbound Links', window.plugin.portalHighlighterOutboundLinkCounter.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,104 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-by-ap-by-energy-relative@vita10gy
|
||||
// @name IITC plugin: highlight portals by ap/energy (relative)
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote AP/Energy value relative to what's currently on the screen. Brighter is better. Orange means your standard 8 down 8 up swap.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP = null;
|
||||
//This is the AP for a run of the mill takedown/putback
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.baseSwapAP = 2350;
|
||||
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var color = 'red';
|
||||
|
||||
if(window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP == null ||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP == null) {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.calculateAPLevels();
|
||||
}
|
||||
var minApE = window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP;
|
||||
var maxApE = window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP;
|
||||
|
||||
if(PLAYER.team !== d.controllingTeam.team) {
|
||||
var ap = getAttackApGain(d);
|
||||
var energy = getCurrentPortalEnergy(d);
|
||||
if(energy < 1) {
|
||||
energy = 1;
|
||||
}
|
||||
portal_ap = ap.enemyAp;
|
||||
|
||||
var opacity = 1;
|
||||
if(minApE !== maxApE) {
|
||||
opacity = ((ap.enemyAp / energy) - minApE) / (maxApE - minApE);
|
||||
}
|
||||
|
||||
if(opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
if(opacity > 1) {
|
||||
opacity = 1;
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.resetAPLevels = function() {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP = null;
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.calculateAPLevels = function() {
|
||||
var displayBounds = map.getBounds();
|
||||
$.each(window.portals, function(qk, portal) {
|
||||
if(displayBounds.contains(portal.getLatLng())) {
|
||||
if(PLAYER.team !== portal.options.details.controllingTeam.team) {
|
||||
var ap = getAttackApGain(portal.options.details);
|
||||
var energy = getCurrentPortalEnergy(portal.options.details);
|
||||
if(energy < 1) {
|
||||
energy = 1;
|
||||
}
|
||||
var portal_ap = ap.enemyAp / energy;
|
||||
if(window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP === null ||
|
||||
portal_ap < window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP) {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP = portal_ap;
|
||||
}
|
||||
if(window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP === null ||
|
||||
portal_ap > window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP) {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP = portal_ap;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('AP/Energy (Relative)', window.plugin.portalHighligherPortalAPPerEnergyRelative.highlight);
|
||||
window.addHook('requestFinished', window.plugin.portalHighligherPortalAPPerEnergyRelative.resetAPLevels);
|
||||
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,99 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-by-ap-relative@vita10gy
|
||||
// @name IITC plugin: highlight portals by ap relative
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote AP value relative to what's currently on the screen. Brighter is better. Orange means your standard 8 down 8 up swap.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalAPRelative = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalAPRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPRelative.maxAP = null;
|
||||
//This is the AP for a run of the mill takedown/putback
|
||||
window.plugin.portalHighligherPortalAPRelative.baseSwapAP = 2350;
|
||||
|
||||
|
||||
window.plugin.portalHighligherPortalAPRelative.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var color = 'red';
|
||||
|
||||
if(window.plugin.portalHighligherPortalAPRelative.minAP == null ||
|
||||
window.plugin.portalHighligherPortalAPRelative.maxAP == null) {
|
||||
window.plugin.portalHighligherPortalAPRelative.calculateAPLevels();
|
||||
}
|
||||
var minAp = window.plugin.portalHighligherPortalAPRelative.minAP;
|
||||
var maxAp = window.plugin.portalHighligherPortalAPRelative.maxAP;
|
||||
|
||||
var ap = getAttackApGain(d);
|
||||
var portal_ap = ap.friendlyAp;
|
||||
|
||||
if(PLAYER.team !== d.controllingTeam.team) {
|
||||
portal_ap = ap.enemyAp;
|
||||
if(portal_ap === window.plugin.portalHighligherPortalAPRelative.baseSwapAP) {
|
||||
color = 'orange';
|
||||
}
|
||||
}
|
||||
|
||||
var opacity = 1;
|
||||
if(minAp !== maxAp) {
|
||||
opacity = (portal_ap - minAp) / (maxAp - minAp);
|
||||
}
|
||||
|
||||
if(opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
if(opacity > 1) {
|
||||
opacity = 1;
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPRelative.resetAPLevels = function() {
|
||||
window.plugin.portalHighligherPortalAPRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPRelative.maxAP = null;
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPRelative.calculateAPLevels = function() {
|
||||
var displayBounds = map.getBounds();
|
||||
$.each(window.portals, function(qk, portal) {
|
||||
if(displayBounds.contains(portal.getLatLng())) {
|
||||
var ap = getAttackApGain(portal.options.details);
|
||||
var portal_ap = ap.friendlyAp;
|
||||
if(PLAYER.team !== portal.options.details.controllingTeam.team) {
|
||||
portal_ap = ap.enemyAp;
|
||||
}
|
||||
if(window.plugin.portalHighligherPortalAPRelative.minAP === null ||
|
||||
portal_ap < window.plugin.portalHighligherPortalAPRelative.minAP) {
|
||||
window.plugin.portalHighligherPortalAPRelative.minAP = portal_ap;
|
||||
}
|
||||
if(window.plugin.portalHighligherPortalAPRelative.maxAP === null ||
|
||||
portal_ap > window.plugin.portalHighligherPortalAPRelative.maxAP) {
|
||||
window.plugin.portalHighligherPortalAPRelative.maxAP = portal_ap;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('AP (Relative)', window.plugin.portalHighligherPortalAPRelative.highlight);
|
||||
window.addHook('requestFinished', window.plugin.portalHighligherPortalAPRelative.resetAPLevels);
|
||||
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,60 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-by-ap@vita10gy
|
||||
// @name IITC plugin: highlight portals by ap
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote AP value. Brighter is better. Orange means your standard 8 down 8 up swap.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalAP = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalAP.minAP = 65;
|
||||
//Anything over max AP will be 100% opacity.
|
||||
window.plugin.portalHighligherPortalAP.maxAP = 6000;
|
||||
//This is the AP for a run of the mill takedown/putback
|
||||
window.plugin.portalHighligherPortalAP.baseSwapAP = 2350;
|
||||
|
||||
|
||||
window.plugin.portalHighligherPortalAP.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var color = 'red';
|
||||
var ap = getAttackApGain(d);
|
||||
var portal_ap = ap.friendlyAp;
|
||||
|
||||
if(PLAYER.team !== d.controllingTeam.team) {
|
||||
portal_ap = ap.enemyAp;
|
||||
if(portal_ap === window.plugin.portalHighligherPortalAP.baseSwapAP) {
|
||||
color = 'orange';
|
||||
}
|
||||
}
|
||||
|
||||
var opacity = (portal_ap - window.plugin.portalHighligherPortalAP.minAP) / window.plugin.portalHighligherPortalAP.maxAP;
|
||||
if(opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
if(opacity > 1) {
|
||||
opacity = 1;
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('AP (Static)', window.plugin.portalHighligherPortalAP.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -31,8 +31,7 @@ window.plugin.portalHighligherPortalsMyLevel.aboveLevel = function(data) {
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalsMyLevel.colorLevel = function(below,data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_level = Math.floor(getPortalLevel(d));
|
||||
var portal_level = data.portal.options.level;
|
||||
var player_level = PLAYER.level;
|
||||
var opacity = .6;
|
||||
if((below && portal_level <= player_level) ||
|
||||
|
@ -1,80 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-upgrade@vita10gy
|
||||
// @name IITC plugin: highlight portals you can upgrade
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.2.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Upgradable - Yellow: you can upgrade it at all. Orange: you can change the level. Red: you can make it your level or higher. To Elite: Yellow - To Level 6. Orange - To Level 7. Red - To Level 8.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalsUpgrade = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalsUpgrade.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var current_level = getPortalLevel(d);
|
||||
var potential_level = window.potentialPortalLevel(d);
|
||||
var player_level = PLAYER.level;
|
||||
var opacity = .7;
|
||||
|
||||
if( potential_level > current_level) {
|
||||
potential_level = Math.floor(potential_level);
|
||||
current_level = Math.floor(current_level);
|
||||
//console.log(potential_level + '>' + current_level);
|
||||
var color = 'yellow';
|
||||
if(potential_level > current_level) {
|
||||
color = 'orange';
|
||||
if(potential_level >= player_level) {
|
||||
color = 'red';
|
||||
}
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalsUpgrade.highlight_elite = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var current_level = getPortalLevel(d);
|
||||
var potential_level = window.potentialPortalLevel(d);
|
||||
var opacity = .8;
|
||||
var color = '';
|
||||
potential_level = Math.floor(potential_level);
|
||||
current_level = Math.floor(current_level);
|
||||
|
||||
if( potential_level > current_level && potential_level >= 6) {
|
||||
switch(potential_level) {
|
||||
case 6:
|
||||
color = 'yellow';
|
||||
break;
|
||||
case 7:
|
||||
color = 'orange';
|
||||
break;
|
||||
case 8:
|
||||
color = 'red';
|
||||
opacity = .9;
|
||||
break;
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Upgradable', window.plugin.portalHighligherPortalsUpgrade.highlight);
|
||||
window.addPortalHighlighter('Upgradable to Elite', window.plugin.portalHighligherPortalsUpgrade.highlight_elite);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,54 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-with-L8-resonators@superd
|
||||
// @name IITC plugin: highlight portals with L8 resonators
|
||||
// @category Highlighter
|
||||
// @category Deleted
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill red of the portals, if portal has L8 res
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalsWithL8Resonators = function() {};
|
||||
|
||||
window.plugin.portalsWithL8Resonators.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var has_L8 = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso) {
|
||||
var level = parseInt(reso.level);
|
||||
if(level == 8)
|
||||
{
|
||||
has_L8+=1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(has_L8 > 0)
|
||||
{
|
||||
var color = 'red';
|
||||
var opa = has_L8 * 0.125;
|
||||
var params = {fillColor: color, fillOpacity: opa};
|
||||
data.portal.setStyle(params);
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Portals with L8 Resonators', window.plugin.portalsWithL8Resonators.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-portal-level-numbers@rongou
|
||||
// @name IITC plugin: Portal Level Numbers
|
||||
// @category Layer
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @version 0.1.2.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -38,8 +38,8 @@ window.plugin.portalLevelNumbers.portalAdded = function(data) {
|
||||
window.plugin.portalLevelNumbers.renderLevel = function(guid,latLng) {
|
||||
plugin.portalLevelNumbers.removeLevel(guid);
|
||||
|
||||
var d = window.portals[guid].options.details;
|
||||
var levelNumber = Math.floor(window.getPortalLevel(d));
|
||||
var p = window.portals[guid];
|
||||
var levelNumber = p.options.level;
|
||||
var level = L.marker(latLng, {
|
||||
icon: L.divIcon({
|
||||
className: 'plugin-portal-level-numbers',
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-portal-names@zaso
|
||||
// @name IITC plugin: Portal Names
|
||||
// @category Layer
|
||||
// @version 0.1.2.@@DATETIMEVERSION@@
|
||||
// @version 0.1.3.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -63,8 +63,8 @@ window.plugin.portalNames.addLabel = function(guid, latLng) {
|
||||
var previousLayer = window.plugin.portalNames.labelLayers[guid];
|
||||
if (!previousLayer) {
|
||||
|
||||
var d = window.portals[guid].options.details;
|
||||
var portalName = d.portalV2.descriptiveText.TITLE;
|
||||
var d = window.portals[guid].options.data;
|
||||
var portalName = d.title;
|
||||
|
||||
var label = L.marker(latLng, {
|
||||
icon: L.divIcon({
|
||||
|
@ -1,453 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-portals-list@teo96
|
||||
// @name IITC plugin: show list of portals
|
||||
// @category Info
|
||||
// @category Deleted
|
||||
// @version 0.0.18.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Display a sortable list of all visible portals with full details about the team, resonators, shields, etc.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
/* whatsnew
|
||||
* 0.0.15: Add 'age' column to display how long each portal has been controlled by its current owner.
|
||||
* 0.0.14: Add support to new mods (S:Shield - T:Turret - LA:Link Amp - H:Heat-sink - M:Multi-hack - FA:Force Amp)
|
||||
* 0.0.12: Use dialog() instead of alert so the user can drag the box around
|
||||
* 0.0.11: Add nominal energy column and # links, fix sort bug when opened even amounts of times, nits
|
||||
* 0.0.10: Fixed persistent css problem with alert
|
||||
* 0.0.9 : bugs hunt
|
||||
* 0.0.8 : Aborted to avoid problems with Niantic (export portals informations as csv or kml file)
|
||||
* 0.0.7 : more informations available via tooltips (who deployed, energy, ...), new E/AP column
|
||||
* 0.0.6 : Add power charge information into a new column + bugfix
|
||||
* 0.0.5 : Filter portals by clicking on 'All portals', 'Res Portals' or 'Enl Portals'
|
||||
* 0.0.4 : Add link to portals name, one click to display full information in portal panel, double click to zoom on portal, hover to show address
|
||||
* 0.0.3 : sorting ascending/descending and add numbers of portals by faction on top on table
|
||||
* 0.0.2 : add sorting feature when click on header column
|
||||
* 0.0.1 : initial release, show list of portals with level, team, resonators and shield information
|
||||
*
|
||||
* Display code inspired from @vita10gy's scoreboard plugin : iitc-plugin-scoreboard@vita10gy - https://github.com/breunigs/ingress-intel-total-conversion
|
||||
* Portal link code from xelio - iitc: AP List - https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/ap-list.user.js
|
||||
*
|
||||
* todo : export as GPX, Open in Google Maps, more statistics in the header, what else ?
|
||||
*/
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalslist = function() {};
|
||||
|
||||
window.plugin.portalslist.listPortals = []; // structure : name, team, level, resonators = Array, Shields = Array, APgain, Age
|
||||
window.plugin.portalslist.sortOrder=-1;
|
||||
window.plugin.portalslist.enlP = 0;
|
||||
window.plugin.portalslist.resP = 0;
|
||||
window.plugin.portalslist.filter=0;
|
||||
|
||||
//fill the listPortals array with portals avaliable on the map (level filtered portals will not appear in the table)
|
||||
window.plugin.portalslist.getPortals = function() {
|
||||
//filter : 0 = All, 1 = Res, 2 = Enl
|
||||
//console.log('** getPortals');
|
||||
var retval=false;
|
||||
|
||||
var displayBounds = map.getBounds();
|
||||
|
||||
window.plugin.portalslist.listPortals = [];
|
||||
//get portals informations from IITC
|
||||
$.each(window.portals, function(i, portal) {
|
||||
// eliminate offscreen portals (selected, and in padding)
|
||||
if(!displayBounds.contains(portal.getLatLng())) return true;
|
||||
|
||||
retval=true;
|
||||
var d = portal.options.details;
|
||||
var name = d.portalV2.descriptiveText.TITLE;
|
||||
var address = d.portalV2.descriptiveText.ADDRESS;
|
||||
var img = getPortalImageUrl(d);
|
||||
var team = portal.options.team;
|
||||
var now = new Date();
|
||||
var now_ms = now.getTime();// + (now.getTimezoneOffset() * 60000);
|
||||
var age_in_seconds = 0;
|
||||
var age_string_long = 'This portal is not captured.';
|
||||
var age_string_short = 'n/a';
|
||||
if(portal.options.details.hasOwnProperty('captured') && portal.options.details.captured.hasOwnProperty('capturedTime')) {
|
||||
var age_in_seconds = Math.floor((now_ms - portal.options.details.captured.capturedTime)/1000);
|
||||
var age_string_long = window.plugin.portalslist.secondsToString(age_in_seconds, 'l');
|
||||
var age_string_short = window.plugin.portalslist.secondsToString(age_in_seconds, 's');
|
||||
}
|
||||
|
||||
switch (team){
|
||||
case 1 :
|
||||
window.plugin.portalslist.resP++;
|
||||
break;
|
||||
case 2 :
|
||||
window.plugin.portalslist.enlP++;
|
||||
break;
|
||||
}
|
||||
var level = getPortalLevel(d).toFixed(2);
|
||||
var guid = portal.options.guid;
|
||||
|
||||
|
||||
//get resonators informations
|
||||
var resonators = []; // my local resonator array : reso level, reso deployed by, distance to portal, energy total, max
|
||||
var energy = 0;
|
||||
var maxenergy=0;
|
||||
$.each(portal.options.details.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso) {
|
||||
resonators[ind] = [reso.level, window.getPlayerName(reso.ownerGuid), reso.distanceToPortal, reso.energyTotal, RESO_NRG[reso.level]];
|
||||
energy += reso.energyTotal;
|
||||
maxenergy += RESO_NRG[reso.level];
|
||||
} else { resonators[ind] = [0,'',0,0,0]; }
|
||||
});
|
||||
// Sort resonators array by resonator level
|
||||
resonators.sort(function (a, b) {return b[0] - a[0]});
|
||||
|
||||
//get mods informations
|
||||
var mods = [];
|
||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
||||
var modShortName='';
|
||||
if (mod) {
|
||||
switch (mod.displayName) {
|
||||
case 'Portal Shield':
|
||||
modShortName = 'S';
|
||||
break;
|
||||
case 'Force Amp':
|
||||
modShortName = 'FA';
|
||||
break;
|
||||
case 'Link Amp':
|
||||
modShortName = 'LA';
|
||||
break;
|
||||
case 'Heat Sink':
|
||||
modShortName = 'H';
|
||||
break;
|
||||
case 'Multi-hack':
|
||||
modShortName = 'M';
|
||||
break;
|
||||
case 'Turret':
|
||||
modShortName = 'T';
|
||||
break;
|
||||
default:
|
||||
modShortName = '';
|
||||
break;
|
||||
}
|
||||
if (modShortName === '') {
|
||||
mods[ind] = ['', '', ''];
|
||||
} else {
|
||||
if ((modShortName === 'S') &&
|
||||
((mod.rarity=='COMMON' && mod.stats.MITIGATION == 6) ||
|
||||
(mod.rarity=='RARE' && mod.stats.MITIGATION == 8) ||
|
||||
(mod.rarity=='VERY_RARE' && mod.stats.MITIGATION == 10)))
|
||||
modShortName=modShortName+'!';
|
||||
mods[ind] = [mod.rarity, getPlayerName(mod.installingUser), modShortName, mod.displayName];
|
||||
}
|
||||
}else { mods[ind] = ['', '', '']; }
|
||||
});
|
||||
|
||||
var APgain= getAttackApGain(d).enemyAp;
|
||||
var thisPortal = {'portal': d,
|
||||
'name': name,
|
||||
'team': team,
|
||||
'level': level,
|
||||
'guid': guid,
|
||||
'resonators': resonators,
|
||||
'energyratio': maxenergy ? Math.floor(energy/maxenergy*100) : 0,
|
||||
'mods': mods,
|
||||
'APgain': APgain,
|
||||
'EAP': (energy/APgain).toFixed(2),
|
||||
'energy': energy,
|
||||
'maxenergy': maxenergy,
|
||||
'links': d.portalV2.linkedEdges.length,
|
||||
'lat': portal._latlng.lat,
|
||||
'lng': portal._latlng.lng,
|
||||
'address': address,
|
||||
'img': img,
|
||||
'age': age_in_seconds,
|
||||
'age_string_long': age_string_long,
|
||||
'age_string_short': age_string_short};
|
||||
window.plugin.portalslist.listPortals.push(thisPortal);
|
||||
});
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
window.plugin.portalslist.displayPL = function() {
|
||||
// debug tools
|
||||
//var start = new Date().getTime();
|
||||
//console.log('***** Start ' + start);
|
||||
|
||||
var html = '';
|
||||
window.plugin.portalslist.sortOrder=-1;
|
||||
window.plugin.portalslist.enlP = 0;
|
||||
window.plugin.portalslist.resP = 0;
|
||||
|
||||
if (window.plugin.portalslist.getPortals()) {
|
||||
html += window.plugin.portalslist.portalTable('level', window.plugin.portalslist.sortOrder,window.plugin.portalslist.filter);
|
||||
} else {
|
||||
html = '<table><tr><td>Nothing to show!</td></tr></table>';
|
||||
};
|
||||
|
||||
dialog({
|
||||
html: '<div id="portalslist">' + html + '</div>',
|
||||
dialogClass: 'ui-dialog-portalslist',
|
||||
title: 'Portal list: ' + window.plugin.portalslist.listPortals.length + ' ' + (window.plugin.portalslist.listPortals.length == 1 ? 'portal' : 'portals'),
|
||||
id: 'portal-list',
|
||||
width: 800
|
||||
});
|
||||
|
||||
//run the name resolving process
|
||||
resolvePlayerNames();
|
||||
|
||||
//debug tools
|
||||
//end = new Date().getTime();
|
||||
//console.log('***** end : ' + end + ' and Elapse : ' + (end - start));
|
||||
}
|
||||
|
||||
window.plugin.portalslist.portalTable = function(sortBy, sortOrder, filter) {
|
||||
// sortOrder <0 ==> desc, >0 ==> asc, i use sortOrder * -1 to change the state
|
||||
window.plugin.portalslist.filter=filter;
|
||||
var portals=window.plugin.portalslist.listPortals;
|
||||
|
||||
//Array sort
|
||||
window.plugin.portalslist.listPortals.sort(function(a, b) {
|
||||
var retVal = 0;
|
||||
switch (sortBy) {
|
||||
case 'names':
|
||||
retVal = a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
|
||||
break;
|
||||
case 'r1':
|
||||
retVal = b.resonators[0][0] - a.resonators[0][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r2':
|
||||
retVal = b.resonators[1][0] - a.resonators[1][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r3':
|
||||
retVal = b.resonators[2][0] - a.resonators[2][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r4':
|
||||
retVal = b.resonators[3][0] - a.resonators[3][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r5':
|
||||
retVal = b.resonators[4][0] - a.resonators[4][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r6':
|
||||
retVal = b.resonators[5][0] - a.resonators[5][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r7':
|
||||
retVal = b.resonators[6][0] - a.resonators[6][0];
|
||||
if (retVal)
|
||||
break;
|
||||
case 'r8':
|
||||
retVal = b.resonators[7][0] - a.resonators[7][0];
|
||||
break;
|
||||
case 's1':
|
||||
retVal = a.mods[0][2] > b.mods[0][2] ? -1 : 1;
|
||||
break;
|
||||
case 's2':
|
||||
retVal = a.mods[1][2] > b.mods[1][2] ? -1 : 1;
|
||||
break;
|
||||
case 's3':
|
||||
retVal = a.mods[2][2] > b.mods[2][2] ? -1 : 1;
|
||||
break;
|
||||
case 's4':
|
||||
retVal = a.mods[3][2] > b.mods[3][2] ? -1 : 1;
|
||||
break;
|
||||
default:
|
||||
retVal = b[sortBy] - a[sortBy];
|
||||
break;
|
||||
}
|
||||
if (sortOrder > 0) retVal = -retVal; //thx @jonatkins
|
||||
return retVal;
|
||||
});
|
||||
|
||||
var sort = window.plugin.portalslist.portalTableSort;
|
||||
var html = window.plugin.portalslist.stats();
|
||||
html += '<table>'
|
||||
+ '<tr><th ' + sort('names', sortBy, -1) + '>Portal</th>'
|
||||
+ '<th ' + sort('level', sortBy, -1) + '>Level</th>'
|
||||
+ '<th title="Team" ' + sort('team', sortBy, -1) + '>T</th>'
|
||||
+ '<th ' + sort('r1', sortBy, -1) + '>R1</th>'
|
||||
+ '<th ' + sort('r2', sortBy, -1) + '>R2</th>'
|
||||
+ '<th ' + sort('r3', sortBy, -1) + '>R3</th>'
|
||||
+ '<th ' + sort('r4', sortBy, -1) + '>R4</th>'
|
||||
+ '<th ' + sort('r5', sortBy, -1) + '>R5</th>'
|
||||
+ '<th ' + sort('r6', sortBy, -1) + '>R6</th>'
|
||||
+ '<th ' + sort('r7', sortBy, -1) + '>R7</th>'
|
||||
+ '<th ' + sort('r8', sortBy, -1) + '>R8</th>'
|
||||
+ '<th ' + sort('energy', sortBy, -1) + '>Energy</th>'
|
||||
+ '<th ' + sort('energyratio', sortBy, -1) + '>%</th>'
|
||||
+ '<th ' + sort('links', sortBy, -1) + '>Links</th>'
|
||||
+ '<th ' + sort('s1', sortBy, -1) + '>M1</th>'
|
||||
+ '<th ' + sort('s2', sortBy, -1) + '>M2</th>'
|
||||
+ '<th ' + sort('s3', sortBy, -1) + '>M3</th>'
|
||||
+ '<th ' + sort('s4', sortBy, -1) + '>M4</th>'
|
||||
+ '<th ' + sort('mitigation', sortBy, -1) + '>Mit.</th>'
|
||||
+ '<th ' + sort('APgain', sortBy, -1) + '>AP Gain</th>'
|
||||
+ '<th title="Energy / AP Gain ratio" ' + sort('EAP', sortBy, -1) + '>E/AP</th>'
|
||||
+ '<th ' + sort('age', sortBy, -1) + '>Age</th></tr>';
|
||||
|
||||
|
||||
$.each(portals, function(ind, portal) {
|
||||
|
||||
if (filter === 0 || filter === portal.team) {
|
||||
html += '<tr class="' + (portal.team === 1 ? 'res' : (portal.team === 2 ? 'enl' : 'neutral')) + '">'
|
||||
+ '<td style="">' + window.plugin.portalslist.getPortalLink(portal.portal, portal.guid) + '</td>'
|
||||
+ '<td class="L' + Math.floor(portal.level) +'">' + portal.level + '</td>'
|
||||
+ '<td style="text-align:center;">' + portal.team + '</td>';
|
||||
|
||||
var mitigationDetails = getPortalMitigationDetails(portal.portal);
|
||||
portal.mitigation = mitigationDetails.total + mitigationDetails.excess;
|
||||
|
||||
var title;
|
||||
var percent;
|
||||
$.each([0, 1, 2, 3 ,4 ,5 ,6 ,7], function(ind, slot) {
|
||||
percent = portal.resonators[slot][4] ? Math.floor(portal.resonators[slot][3]/portal.resonators[slot][4]*100) : 0;
|
||||
title = 'title="owner: <b>' + portal.resonators[slot][1] + '</b><br>'
|
||||
+ 'energy: ' + portal.resonators[slot][3] + ' / ' + portal.resonators[slot][4] + ' (' + percent + '%)<br>'
|
||||
+ 'distance: ' + portal.resonators[slot][2] + 'm';
|
||||
|
||||
html += '<td class="L' + portal.resonators[slot][0] +'" ' + title + '">' + portal.resonators[slot][0] + '</td>';
|
||||
|
||||
});
|
||||
|
||||
html += '<td style="cursor:help" title="'+ portal.energy +'">' + prettyEnergy(portal.energy) + '</td>'
|
||||
+ '<td style="cursor:help" title="' + portal.energy + ' / ' + portal.maxenergy +'">' + portal.energyratio + '%</td>'
|
||||
+ '<td style="cursor:help" title="' + portal.links + '">' + portal.links + '</td>'
|
||||
+ '<td style="cursor:help; background-color: '+COLORS_MOD[portal.mods[0][0]]+';" title="Mod : ' + portal.mods[0][3] + '\nInstalled by : ' + portal.mods[0][1] + '\nRarity : ' + portal.mods[0][0] + '">' + portal.mods[0][2] + '</td>'
|
||||
+ '<td style="cursor:help; background-color: '+COLORS_MOD[portal.mods[1][0]]+';" title="Mod : ' + portal.mods[1][3] + '\nInstalled by : ' + portal.mods[1][1] + '\nRarity : ' + portal.mods[1][0] + '">' + portal.mods[1][2] + '</td>'
|
||||
+ '<td style="cursor:help; background-color: '+COLORS_MOD[portal.mods[2][0]]+';" title="Mod : ' + portal.mods[2][3] + '\nInstalled by : ' + portal.mods[2][1] + '\nRarity : ' + portal.mods[2][0] + '">' + portal.mods[2][2] + '</td>'
|
||||
+ '<td style="cursor:help; background-color: '+COLORS_MOD[portal.mods[3][0]]+';" title="Mod : ' + portal.mods[3][3] + '\nInstalled by : ' + portal.mods[3][1] + '\nRarity : ' + portal.mods[3][0] + '">' + portal.mods[3][2] + '</td>'
|
||||
+ '<td>' + portal.mitigation + '</td>'
|
||||
+ '<td>' + portal.APgain + '</td>'
|
||||
+ '<td>' + portal.EAP + '</td>'
|
||||
+ '<td style="cursor:help;" title="' + portal.age_string_long + '">' + portal.age_string_short + '</td>';
|
||||
|
||||
html+= '</tr>';
|
||||
}
|
||||
});
|
||||
html += '</table>';
|
||||
|
||||
html += '<div class="disclaimer">Click on portals table headers to sort by that column. '
|
||||
+ 'Click on <b>All Portals, Resistance Portals, Enlightened Portals</b> to filter<br>'
|
||||
+ 'Thanks to @vita10gy & @xelio for their IITC plugins who inspired me. A <a href="https://plus.google.com/113965246471577467739">@teo96</a> production. Vive la Résistance !</div>';
|
||||
|
||||
window.plugin.portalslist.sortOrder = window.plugin.portalslist.sortOrder*-1;
|
||||
return html;
|
||||
}
|
||||
|
||||
window.plugin.portalslist.stats = function(sortBy) {
|
||||
//console.log('** stats');
|
||||
var html = '<table><tr>'
|
||||
+ '<td class="filterAll" style="cursor:pointer" onclick="window.plugin.portalslist.portalTable(\'level\',-1,0)"><a href=""></a>All Portals : (click to filter)</td><td class="filterAll">' + window.plugin.portalslist.listPortals.length + '</td>'
|
||||
+ '<td class="filterRes" style="cursor:pointer" class="sorted" onclick="window.plugin.portalslist.portalTable(\'level\',-1,1)">Resistance Portals : </td><td class="filterRes">' + window.plugin.portalslist.resP +' (' + Math.floor(window.plugin.portalslist.resP/window.plugin.portalslist.listPortals.length*100) + '%)</td>'
|
||||
+ '<td class="filterEnl" style="cursor:pointer" class="sorted" onclick="window.plugin.portalslist.portalTable(\'level\',-1,2)">Enlightened Portals : </td><td class="filterEnl">'+ window.plugin.portalslist.enlP +' (' + Math.floor(window.plugin.portalslist.enlP/window.plugin.portalslist.listPortals.length*100) + '%)</td>'
|
||||
+ '</tr>'
|
||||
+ '</table>';
|
||||
return html;
|
||||
}
|
||||
|
||||
// A little helper function so the above isn't so messy
|
||||
window.plugin.portalslist.portalTableSort = function(name, by) {
|
||||
var retVal = 'data-sort="' + name + '"';
|
||||
if(name === by) {
|
||||
retVal += ' class="sorted"';
|
||||
}
|
||||
return retVal;
|
||||
};
|
||||
|
||||
// portal link - single click: select portal
|
||||
// double click: zoom to and select portal
|
||||
// hover: show address
|
||||
// code from getPortalLink function by xelio from iitc: AP List - https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/ap-list.user.js
|
||||
window.plugin.portalslist.getPortalLink = function(portal,guid) {
|
||||
|
||||
var latlng = [portal.locationE6.latE6/1E6, portal.locationE6.lngE6/1E6].join();
|
||||
var jsSingleClick = 'window.renderPortalDetails(\''+guid+'\');return false';
|
||||
var jsDoubleClick = 'window.zoomToAndShowPortal(\''+guid+'\', ['+latlng+']);return false';
|
||||
var perma = '/intel?latE6='+portal.locationE6.latE6+'&lngE6='+portal.locationE6.lngE6+'&z=17&pguid='+guid;
|
||||
|
||||
//Use Jquery to create the link, which escape characters in TITLE and ADDRESS of portal
|
||||
var a = $('<a>',{
|
||||
"class": 'help',
|
||||
text: portal.portalV2.descriptiveText.TITLE,
|
||||
title: portal.portalV2.descriptiveText.ADDRESS,
|
||||
href: perma,
|
||||
onClick: jsSingleClick,
|
||||
onDblClick: jsDoubleClick
|
||||
})[0].outerHTML;
|
||||
var div = '<div class="portalTitle">'+a+'</div>';
|
||||
return div;
|
||||
}
|
||||
|
||||
// length can be "s" or "l" for "short" or "long"
|
||||
window.plugin.portalslist.secondsToString = function(seconds, length) {
|
||||
var numdays = Math.floor(seconds / 86400);
|
||||
var numhours = Math.floor((seconds % 86400) / 3600);
|
||||
var numminutes = Math.floor(((seconds % 86400) % 3600) / 60);
|
||||
var numseconds = ((seconds % 86400) % 3600) % 60;
|
||||
if(length === "l") {
|
||||
return numdays + " days " + numhours + " hours " + numminutes + " minutes " + numseconds + " seconds";
|
||||
} else {
|
||||
return numdays + "d" + numhours + "h";
|
||||
}
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
$('#toolbox').append(' <a onclick="window.plugin.portalslist.displayPL()" title="Display a list of portals in the current view">Portals list</a>');
|
||||
$('head').append('<style>' +
|
||||
//style.css sets dialog max-width to 700px - override that here
|
||||
// (the width: 800 parameter to dialog is NOT enough to override that css limit)
|
||||
'#dialog-portal-list {max-width: 800px !important;}' +
|
||||
'#portalslist table {margin-top:5px; border-collapse: collapse; empty-cells: show; width:100%; clear: both;}' +
|
||||
'#portalslist table td, #portalslist table th {border-bottom: 1px solid #0b314e; padding:3px; color:white; background-color:#1b415e}' +
|
||||
'#portalslist table tr.res td { background-color: #005684; }' +
|
||||
'#portalslist table tr.enl td { background-color: #017f01; }' +
|
||||
'#portalslist table tr.neutral td { background-color: #000000; }' +
|
||||
'#portalslist table th { text-align: center;}' +
|
||||
'#portalslist table td { text-align: center;}' +
|
||||
'#portalslist table td.L0 { cursor: help; background-color: #000000 !important;}' +
|
||||
'#portalslist table td.L1 { cursor: help; background-color: #FECE5A !important;}' +
|
||||
'#portalslist table td.L2 { cursor: help; background-color: #FFA630 !important;}' +
|
||||
'#portalslist table td.L3 { cursor: help; background-color: #FF7315 !important;}' +
|
||||
'#portalslist table td.L4 { cursor: help; background-color: #E40000 !important;}' +
|
||||
'#portalslist table td.L5 { cursor: help; background-color: #FD2992 !important;}' +
|
||||
'#portalslist table td.L6 { cursor: help; background-color: #EB26CD !important;}' +
|
||||
'#portalslist table td.L7 { cursor: help; background-color: #C124E0 !important;}' +
|
||||
'#portalslist table td.L8 { cursor: help; background-color: #9627F4 !important;}' +
|
||||
'#portalslist table td:nth-child(1) { text-align: left;}' +
|
||||
'#portalslist table th { cursor:pointer; text-align: right;}' +
|
||||
'#portalslist table th:nth-child(1) { text-align: left;}' +
|
||||
'#portalslist table th.sorted { color:#FFCE00; }' +
|
||||
'#portalslist .filterAll { margin-top: 10px;}' +
|
||||
'#portalslist .filterRes { margin-top: 10px; background-color: #005684 }' +
|
||||
'#portalslist .filterEnl { margin-top: 10px; background-color: #017f01 }' +
|
||||
'#portalslist .disclaimer { margin-top: 10px; font-size:10px; }' +
|
||||
'#portalslist .portalTitle { display: inline-block; width: 160px !important; min-width: 160px !important; max-width: 160px !important; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }' +
|
||||
'</style>');
|
||||
// Setup sorting
|
||||
$(document).on('click.portalslist', '#portalslist table th', function() {
|
||||
$('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,window.plugin.portalslist.filter));
|
||||
});
|
||||
$(document).on('click.portalslist', '#portalslist .filterAll', function() {
|
||||
$('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,0));
|
||||
});
|
||||
$(document).on('click.portalslist', '#portalslist .filterRes', function() {
|
||||
$('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,1));
|
||||
});
|
||||
$(document).on('click.portalslist', '#portalslist .filterEnl', function() {
|
||||
$('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,2));
|
||||
});
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -1,340 +1,15 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-scoreboard@vita10gy
|
||||
// @name IITC plugin: show a localized scoreboard.
|
||||
// @category Info
|
||||
// @category Deleted
|
||||
// @version 0.1.9.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] A localized scoreboard.
|
||||
// @description PLUGIN CURRENTLY UNAVAILABLE
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
@@PLUGINSTART@@
|
||||
|
||||
// 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]['count_mods'] = 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_mods'] = 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);
|
||||
|
||||
// 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]['count_fields']++;
|
||||
scores['team'][team]['field_area'] += fieldArea;
|
||||
val.options.data.fieldArea = fieldArea;
|
||||
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);
|
||||
|
||||
scores['team'][team]['count_links']++;
|
||||
|
||||
var linkLength = window.plugin.scoreboard.portalDistance(link.options.data.edge.destinationPortalLocation,link.options.data.edge.originPortalLocation);
|
||||
scores['team'][team]['link_length'] += linkLength;
|
||||
|
||||
var largestLink = scores['team'][team]['largest']['link'];
|
||||
if(largestLink === undefined || largestLink.distance < linkLength) {
|
||||
largestLink = {};
|
||||
largestLink.distance = linkLength;
|
||||
}
|
||||
scores['team'][team]['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) {
|
||||
window.plugin.scoreboard.initPlayer(mod.installingUser, team);
|
||||
somethingInView = true;
|
||||
scores['team'][team]['count_mods']++;
|
||||
scores['player'][mod.installingUser]['count_mods']++;
|
||||
}
|
||||
});
|
||||
|
||||
$.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.teamTableRow = function(field,title) {
|
||||
var scores = window.plugin.scoreboard.scores['team'];
|
||||
var retVal = '<tr><td>'
|
||||
+ title
|
||||
+ '</td><td class="number">'
|
||||
+ window.digits(Math.round(scores[TEAM_RES][field]))
|
||||
+ '</td><td class="number">'
|
||||
+ window.digits(Math.round(scores[TEAM_ENL][field]))
|
||||
+ '</td><td class="number">'
|
||||
+ window.digits(Math.round(scores[TEAM_RES][field] + scores[TEAM_ENL][field]))
|
||||
+ '</td></tr>';
|
||||
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 = '<div title="' + title + '">'
|
||||
+ window.digits(Math.round(field.options.data.fieldArea))
|
||||
+ '</div>';
|
||||
|
||||
} else {
|
||||
retVal = 'N/A';
|
||||
}
|
||||
return retVal;
|
||||
};
|
||||
|
||||
window.plugin.scoreboard.playerTableRow = function(playerGuid) {
|
||||
var scores = window.plugin.scoreboard.scores['player'];
|
||||
var retVal = '<tr class="'
|
||||
+ (scores[playerGuid]['team'] === TEAM_RES ? 'res' : 'enl')
|
||||
+'"><td>'
|
||||
+ window.getPlayerName(playerGuid);
|
||||
+ '</td>';
|
||||
|
||||
$.each(['count_portals','count_resonators','count_mods'], function(i, field) {
|
||||
retVal += '<td class="number">'
|
||||
+ window.digits(Math.round(scores[playerGuid][field]))
|
||||
+ '</td>';
|
||||
});
|
||||
retVal += '</tr>';
|
||||
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 = '<table>'
|
||||
+ '<tr><th ' + sort('names', sortBy) + '>Player</th>'
|
||||
+ '<th ' + sort('count_portals', sortBy) + '>Portals</th>'
|
||||
+ '<th ' + sort('count_resonators', sortBy) + '>Resonators</th>'
|
||||
+ '<th ' + sort('count_mods', sortBy) + '>Mods</th></tr>';
|
||||
$.each(window.plugin.scoreboard.playerGuids, function(index, guid) {
|
||||
scoreHtml += window.plugin.scoreboard.playerTableRow(guid);
|
||||
});
|
||||
scoreHtml += '</table>';
|
||||
|
||||
return scoreHtml;
|
||||
}
|
||||
|
||||
// A little helper function 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 scoreHtml = '';
|
||||
var title = '';
|
||||
|
||||
if(somethingInView) {
|
||||
scoreHtml += '<table>'
|
||||
+ '<tr><th></th><th class="number">Resistance</th><th class="number">Enlightened</th><th class="number">Total</th></tr>'
|
||||
+ 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')
|
||||
+ window.plugin.scoreboard.teamTableRow('count_mods','Mods')
|
||||
+ '</table>';
|
||||
|
||||
scoreHtml += '<table>'
|
||||
+ '<tr><th></th><th>Resistance</th><th>Enlightened</th></tr>'
|
||||
+ '<tr><td>Largest Field (km²)</td><td>'
|
||||
+ window.plugin.scoreboard.fieldInfoArea(scores['team'][TEAM_RES]['largest']['field_area'])
|
||||
+ '</td><td>'
|
||||
+ window.plugin.scoreboard.fieldInfoArea(scores['team'][TEAM_ENL]['largest']['field_area'])
|
||||
+ '</td></tr>'
|
||||
+ '<tr><td>Longest Link (m)</td><td>';
|
||||
if(scores['team'][TEAM_RES]['largest']['link'] === undefined) {
|
||||
scoreHtml += 'N/A';
|
||||
}
|
||||
else {
|
||||
scoreHtml += window.digits(Math.round(scores['team'][TEAM_RES]['largest']['link']['distance']));
|
||||
}
|
||||
scoreHtml += '</td><td>';
|
||||
|
||||
if(scores['team'][TEAM_ENL]['largest']['link'] === undefined) {
|
||||
scoreHtml += 'N/A';
|
||||
}
|
||||
else {
|
||||
scoreHtml += window.digits(Math.round(scores['team'][TEAM_ENL]['largest']['link']['distance']));
|
||||
}
|
||||
scoreHtml += '</td></tr>'
|
||||
+ '</table>'
|
||||
+ '<div id="players">'
|
||||
+ window.plugin.scoreboard.playerTable('count_portals')
|
||||
+ '</div>';
|
||||
|
||||
scoreHtml += '<div class="disclaimer">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.</div>';
|
||||
} else {
|
||||
scoreHtml += 'You need something in view.';
|
||||
title = 'nothing in view';
|
||||
}
|
||||
|
||||
dialog({
|
||||
html: '<div id="scoreboard">' + scoreHtml + '</div>',
|
||||
title: 'Scoreboard: ' + title,
|
||||
dialogClass: 'ui-dialog-scoreboard',
|
||||
id: 'scoreboard'
|
||||
});
|
||||
|
||||
//run the name resolving process
|
||||
resolvePlayerNames();
|
||||
}
|
||||
|
||||
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(' <a onclick="window.plugin.scoreboard.display()" title="Display a scoreboard per team for the current view">Scoreboard</a>');
|
||||
$('head').append('<style>' +
|
||||
'.ui-dialog-scoreboard {width: auto !important; min-width: 400px !important; max-width: 600px !important;}' +
|
||||
'#scoreboard table {margin-top:10px; border-collapse: collapse; empty-cells: show; width:100%; clear: both;}' +
|
||||
'#scoreboard table td, #scoreboard table th {border-bottom: 1px solid #0b314e; padding:3px; color:white; background-color:#1b415e}' +
|
||||
'#scoreboard table tr.res td { background-color: #005684; }' +
|
||||
'#scoreboard table tr.enl td { background-color: #017f01; }' +
|
||||
'#scoreboard table tr:nth-child(even) td { opacity: .8 }' +
|
||||
'#scoreboard table tr:nth-child(odd) td { color: #ddd !important; }' +
|
||||
'#scoreboard table th { text-align:left }' +
|
||||
'#scoreboard table td.number, #scoreboard table th.number { text-align:right }' +
|
||||
'#players table th { cursor:pointer; text-align: right;}' +
|
||||
'#players table th:nth-child(1) { text-align: left;}' +
|
||||
'#scoreboard table th.sorted { color:#FFCE00; }' +
|
||||
'#scoreboard .disclaimer { margin-top:10px; font-size:10px; }' +
|
||||
'.mu_score { margin-bottom: 10px; }' +
|
||||
'.mu_score span { overflow: hidden; padding-top:2px; padding-bottom: 2px; display: block; font-weight: bold; float: left; box-sizing: border-box; -moz-box-sizing:border-box; -webkit-box-sizing:border-box; }' +
|
||||
'.mu_score span.res { background-color: #005684; text-align: right; padding-right:4px; }' +
|
||||
'.mu_score span.enl { background-color: #017f01; padding-left: 4px; }' +
|
||||
'</style>');
|
||||
// Setup sorting
|
||||
$(document).on('click', '#players table th', function() {
|
||||
$('#players').html(window.plugin.scoreboard.playerTable($(this).data('sort')));
|
||||
});
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
@@PLUGINEND@@
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-show-linked-portals@fstopienski
|
||||
// @name IITC plugin: Show linked portals
|
||||
// @category Portal Info
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -35,6 +35,7 @@ window.plugin.showLinkedPortal.handleUpdate = function () {
|
||||
}
|
||||
|
||||
window.plugin.showLinkedPortal.portalDetail = function (data) {
|
||||
|
||||
// don't render linked portal data if portal is neutral.
|
||||
// (the data can remain sometimes - when a portal decays?)
|
||||
if (data.portalDetails.controllingTeam.team == 'NEUTRAL')
|
||||
@ -51,20 +52,17 @@ window.plugin.showLinkedPortal.portalDetail = function (data) {
|
||||
|
||||
$('.showLinkedPortalLink:not(.outOfRange)').bind('click', function () {
|
||||
var guid = $(this).attr('data-guid');
|
||||
if (window.portals[guid] !== undefined) {
|
||||
window.selectPortal($(this).attr('data-guid'));
|
||||
window.renderPortalDetails(window.selectedPortal);
|
||||
var portalDetails = window.portals[guid].options.details;
|
||||
var lat0 = portalDetails.locationE6.latE6 / 1E6;
|
||||
var lon0 = portalDetails.locationE6.lngE6 / 1E6;
|
||||
var Rlatlng = [lat0, lon0];
|
||||
map.setView(Rlatlng, map.getZoom());
|
||||
}
|
||||
else {
|
||||
// TODO: instead of just zooming out one level, check the link data for the start+end coordinates,
|
||||
// and fit the map view to the bounding box
|
||||
map.setZoom((map.getZoom() - 1));
|
||||
window.renderPortalDetails(guid);
|
||||
var latlng = findPortalLatLng(guid);
|
||||
if (latlng) {
|
||||
if (!map.getBounds().pad(-0.1).contains(latlng)) {
|
||||
map.panTo(latlng);
|
||||
}
|
||||
} else {
|
||||
// no idea where this portal is(!) - so step back one zoom level
|
||||
map.setZoom(map.getZoom()-1);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -74,7 +72,7 @@ window.plugin.showLinkedPortal.getPortalByGuid = function (guid,isorigin) {
|
||||
var portalInfoString;
|
||||
|
||||
if (window.portals[guid] !== undefined) {
|
||||
var portalDetails = window.portals[guid].options.details;
|
||||
var portalData = window.portals[guid].options.data;
|
||||
|
||||
var portalNameAddressAlt = "'" + portalDetails.portalV2.descriptiveText.TITLE + "' (" + portalDetails.portalV2.descriptiveText.ADDRESS + ")";
|
||||
var portalNameAddressTitle = $('<div/>').append($('<strong/>').text(portalDetails.portalV2.descriptiveText.TITLE))
|
||||
@ -90,7 +88,7 @@ window.plugin.showLinkedPortal.getPortalByGuid = function (guid,isorigin) {
|
||||
.attr('title', portalNameAddressTitle))
|
||||
.html();
|
||||
} else {
|
||||
var title = $('<div/>').append($('<strong/>').text('Zoom out'))
|
||||
var title = $('<div/>').append($('<strong/>').text('Go to portal'))
|
||||
.append($('<br/>'))
|
||||
.append(linkDirection)
|
||||
.html();
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-show-portal-weakness@vita10gy
|
||||
// @name IITC plugin: show portal weakness
|
||||
// @category Highlighter
|
||||
// @version 0.7.1.@@DATETIMEVERSION@@
|
||||
// @version 0.7.2.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -22,66 +22,28 @@
|
||||
window.plugin.portalWeakness = function() {};
|
||||
|
||||
window.plugin.portalWeakness.highlightWeakness = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_weakness = 0;
|
||||
if(getTeam(d) !== 0) {
|
||||
var only_mods = true;
|
||||
var missing_mods = 0;
|
||||
if(window.getTotalPortalEnergy(d) > 0 && window.getCurrentPortalEnergy(d) < window.getTotalPortalEnergy(d)) {
|
||||
portal_weakness = 1 - (window.getCurrentPortalEnergy(d)/window.getTotalPortalEnergy(d));
|
||||
only_mods = false;
|
||||
}
|
||||
//Ding the portal for every unapplicable mod.
|
||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
||||
if(mod === null || mod.type == 'MULTIHACK' || mod.type == 'HEATSINK' || mod.type == 'LINK_AMPLIFIER') {
|
||||
if(mod === null) {
|
||||
missing_mods++;
|
||||
}
|
||||
portal_weakness += .08;
|
||||
}
|
||||
});
|
||||
//Ding the portal for every missing resonator.
|
||||
var resCount = 0;
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if(reso === null) {
|
||||
portal_weakness += .125;
|
||||
only_mods = false;
|
||||
} else {
|
||||
resCount++;
|
||||
}
|
||||
});
|
||||
if(portal_weakness < 0) {
|
||||
portal_weakness = 0;
|
||||
}
|
||||
if(portal_weakness > 1) {
|
||||
portal_weakness = 1;
|
||||
}
|
||||
|
||||
if(portal_weakness > 0) {
|
||||
var fill_opacity = portal_weakness*.85 + .15;
|
||||
var color = 'orange';
|
||||
if(only_mods) {
|
||||
color = 'yellow';
|
||||
//If only mods are missing, make portal yellow
|
||||
// but fill more than usual since pale yellow is basically invisible
|
||||
fill_opacity = missing_mods*.15 + .1;
|
||||
} else if(missing_mods > 0) {
|
||||
color = 'red';
|
||||
}
|
||||
fill_opacity = Math.round(fill_opacity*100)/100;
|
||||
if(data.portal.options.team != TEAM_NONE) {
|
||||
var res_count = data.portal.options.data.resCount;
|
||||
var portal_health = data.portal.options.data.health;
|
||||
|
||||
var strength = (res_count/8) * (portal_health/100);
|
||||
|
||||
if(strength < 1) {
|
||||
var fill_opacity = (1-strength)*.85 + .15;
|
||||
var color = 'red';
|
||||
var params = {fillColor: color, fillOpacity: fill_opacity};
|
||||
if(resCount < 8) {
|
||||
// Hole per missing resonator
|
||||
var dash = new Array(8-resCount + 1).join("1,4,") + "100,0"
|
||||
params["dashArray"] = dash;
|
||||
|
||||
// Hole per missing resonator
|
||||
if (res_count < 8) {
|
||||
var dash = new Array((8 - res_count) + 1).join("1,4,") + "100,0"
|
||||
params.dashArray = dash;
|
||||
}
|
||||
|
||||
data.portal.setStyle(params);
|
||||
} else {
|
||||
data.portal.setStyle({fillColor: COLORS[getTeam(data.portal.options.details)],
|
||||
fillOpacity: 0.5,
|
||||
dashArray: null});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// @id iitc-plugin-zaprange@zaso
|
||||
// @name IITC plugin: Zaprange
|
||||
// @category Layer
|
||||
// @version 0.1.2.@@DATETIMEVERSION@@
|
||||
// @version 0.1.3.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -25,11 +25,11 @@
|
||||
|
||||
window.plugin.zaprange.portalAdded = function(data) {
|
||||
data.portal.on('add', function() {
|
||||
window.plugin.zaprange.draw(this.options.guid, this.options.details.controllingTeam.team);
|
||||
window.plugin.zaprange.draw(this.options.guid, this.options.data.team);
|
||||
});
|
||||
|
||||
data.portal.on('remove', function() {
|
||||
window.plugin.zaprange.remove(this.options.guid, this.options.details.controllingTeam.team);
|
||||
window.plugin.zaprange.remove(this.options.guid, this.options.data.team);
|
||||
});
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
if(faction !== "NEUTRAL") {
|
||||
var coo = d._latlng;
|
||||
var latlng = new L.LatLng(coo.lat,coo.lng);
|
||||
var portalLevel = parseInt(getPortalLevel(d.options.details));
|
||||
var portalLevel = d.options.level;
|
||||
var optCircle = {color:'red',opacity:0.7,fillColor:'red',fillOpacity:0.1,weight:1,clickable:false, dashArray: [10,6]};
|
||||
var range = (5*portalLevel)+35;
|
||||
|
||||
|
Reference in New Issue
Block a user