// ==UserScript== // @id iitc-plugin-compute-ap-stats@Hollow011 // @name IITC plugin: Compute AP statistics // @category Info // @version 0.4.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://*.ingress.com/intel* // @include http://*.ingress.com/intel* // @match https://*.ingress.com/intel* // @match http://*.ingress.com/intel* // @include https://*.ingress.com/mission/* // @include http://*.ingress.com/mission/* // @match https://*.ingress.com/mission/* // @match http://*.ingress.com/mission/* // @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('
'); $('#available_ap_display').css({'color':'#ffce00', 'font-size':'90%', 'padding':'4px 2px'}); // do an initial calc for sidebar sizing purposes window.plugin.compAPStats.update(false); // make the value update when the map data updates window.addHook('mapDataRefreshEnd', window.plugin.compAPStats.mapDataRefreshEnd); window.addHook('requestFinished', window.plugin.compAPStats.requestFinished); } window.plugin.compAPStats.mapDataRefreshEnd = function() { if (window.plugin.compAPStats.timer) { clearTimeout(window.plugin.compAPStats.timer); window.plugin.compAPStats.timer = undefined; } window.plugin.compAPStats.update(true); } window.plugin.compAPStats.requestFinished = function() { // process on a short delay, so if multiple requests finish in a short time we only calculate once if (window.plugin.compAPStats.timer === undefined) { window.plugin.compAPStats.timer = setTimeout( function() { window.plugin.compAPStats.timer = undefined; window.plugin.compAPStats.update(false); }, 0.75*1000); } } window.plugin.compAPStats.update = function(hasFinished) { var result = window.plugin.compAPStats.compAPStats(); var loading = hasFinished ? '' : 'Loading...'; var formatRow = function(team,data) { var title = 'Destroy and capture '+data.destroyPortals+' portals\n' + 'Destroy '+data.destroyLinks+' links and '+data.destroyFields+' fields\n' + 'Capture '+data.capturePortals+' neutral portals, complete '+data.finishPortals+' portals\n' + '(unknown additional AP for links/fields)'; return ''+team+''+digits(data.AP)+''; } $('#available_ap_display').html('Available AP in this area: ' + loading + '' + formatRow('Enlightened',result.enl) + formatRow('Resistance', result.res) + '
'); } window.plugin.compAPStats.compAPStats = function() { var result = { res: { AP: 0, destroyPortals: 0, capturePortals: 0, finishPortals: 0, destroyLinks: 0, destroyFields: 0 }, enl: { AP: 0, destroyPortals: 0, capturePortals: 0, finishPortals: 0, destroyLinks: 0, destroyFields: 0 }, }; var displayBounds = map.getBounds(); // AP to fully deploy a neutral portal var PORTAL_FULL_DEPLOY_AP = CAPTURE_PORTAL + 8*DEPLOY_RESONATOR + COMPLETION_BONUS; // Grab every portal in the viewable area and compute individual AP stats // (fields and links are counted separately below) $.each(window.portals, function(ind, portal) { var data = portal.options.data; // eliminate offscreen portals if(!displayBounds.contains(portal.getLatLng())) return true; //$.each 'continue' // AP to complete a portal - assuming it's already captured (so no CAPTURE_PORTAL) var completePortalAp = 0; var isFullyDeployed = data.resCount == 8; if (!isFullyDeployed) { completePortalAp = data.resCount != 8 ? (8-data.resCount)*DEPLOY_RESONATOR + COMPLETION_BONUS : 0; } // AP to destroy this portal var destroyAp = data.resCount * DESTROY_RESONATOR; if (portal.options.team == TEAM_ENL) { result.res.AP += destroyAp + PORTAL_FULL_DEPLOY_AP; result.res.destroyPortals++; if (!isFullyDeployed) { result.enl.AP += completePortalAp; result.enl.finishPortals++; } } else if (portal.options.team == TEAM_RES) { result.enl.AP += destroyAp + PORTAL_FULL_DEPLOY_AP; result.enl.destroyPortals++; if (!isFullyDeployed) { result.res.AP += completePortalAp; result.res.finishPortals++; } } else { // it's a neutral portal, potential for both teams. by definition no fields or edges result.enl.AP += PORTAL_FULL_DEPLOY_AP; result.enl.capturePortals++; result.res.AP += PORTAL_FULL_DEPLOY_AP; result.res.capturePortals++; } }); // now every link that starts/ends at a point on screen $.each(window.links, function(guid, link) { // only consider links that start/end on-screen var points = link.getLatLngs(); if (displayBounds.contains(points[0]) || displayBounds.contains(points[1])) { if (link.options.team == TEAM_ENL) { result.res.AP += DESTROY_LINK; result.res.destroyLinks++; } else if (link.options.team == TEAM_RES) { result.enl.AP += DESTROY_LINK; result.enl.destroyLinks++; } } }); // and now all fields that have a vertex on screen $.each(window.fields, function(guid, field) { // only consider fields with at least one vertex on screen var points = field.getLatLngs(); if (displayBounds.contains(points[0]) || displayBounds.contains(points[1]) || displayBounds.contains(points[2])) { if (field.options.team == TEAM_ENL) { result.res.AP += DESTROY_FIELD; result.res.destroyFields++; } else if (field.options.team == TEAM_RES) { result.enl.AP += DESTROY_FIELD; result.enl.destroyFields++; } } }); return result; } var setup = function() { window.plugin.compAPStats.setupCallback(); } // PLUGIN END ////////////////////////////////////////////////////////// @@PLUGINEND@@