This commit is contained in:
vita10gy 2013-03-05 22:55:26 -06:00
parent 62cf315797
commit 8573675d98
17 changed files with 220 additions and 53 deletions

View File

@ -76,6 +76,7 @@ First of all, its very nice you want to help. There are several equally impor
[boombuler](https://github.com/boombuler),
[cmrn](https://github.com/cmrn),
[epf](https://github.com/epf),
[Fragger](https://github.com/Fragger),
[integ3r](https://github.com/integ3r),
[j16sdiz](https://github.com/j16sdiz),
[JasonMillward](https://github.com/JasonMillward),

View File

@ -159,11 +159,13 @@ window.setupMap = function() {
// included as inline script in the original site, the data is static
// and cannot be updated.
window.setupPlayerStat = function() {
PLAYER.guid = playerNameToGuid(PLAYER.nickname);
var level;
var ap = parseInt(PLAYER.ap);
for(level = 0; level < MIN_AP_FOR_LEVEL.length; level++) {
if(ap < MIN_AP_FOR_LEVEL[level]) break;
}
PLAYER.level = level;
var thisLvlAp = MIN_AP_FOR_LEVEL[level-1];
var nextLvlAp = MIN_AP_FOR_LEVEL[level] || ap;

View File

@ -46,14 +46,15 @@
// checkRenderLimit: callback is passed the argument of
// {reached : false} to indicate that the renderlimit is reached
// set reached to true.
// requestFinished: called after each request finished. Argument is
// {success: boolean} indicated the request success or fail.
window._hooks = {}
window.VALID_HOOKS = ['portalAdded', 'portalDetailsUpdated',
'publicChatDataAvailable', 'portalDataLoaded', 'beforePortalReRender',
'checkRenderLimit'];
'checkRenderLimit', 'requestFinished'];
window.runHooks = function(event, data) {
if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event);

View File

@ -59,6 +59,7 @@ window.handleFailedRequest = function() {
var leftOverPortals = portalRenderLimit.mergeLowLevelPortals(null);
handlePortalsRender(leftOverPortals);
}
runHooks('requestFinished', {success: false});
}
// works on map data response and ensures entities are drawn/updated.
@ -139,6 +140,7 @@ window.handleDataResponse = function(data, textStatus, jqXHR) {
resolvePlayerNames();
renderUpdateStatus();
runHooks('requestFinished', {success: true});
}
window.handlePortalsRender = function(portals) {
@ -197,10 +199,13 @@ window.cleanUp = function() {
cnt[1]++;
linksLayer.removeLayer(link);
});
fieldsLayer.eachLayer(function(field) {
if(b.intersects(field.getBounds())) return;
cnt[2]++;
fieldsLayer.removeLayer(field);
fieldsLayer.eachLayer(function(fieldgroup) {
fieldgroup.eachLayer(function(item) {
if(!item.options.guid) return true; // Skip MU div container as this doesn't have the bounds we need
if(b.intersects(item.getBounds())) return;
cnt[2]++;
fieldsLayer.removeLayer(fieldgroup);
});
});
console.log('removed out-of-bounds: '+cnt[0]+' portals, '+cnt[1]+' links, '+cnt[2]+' fields');
}
@ -448,6 +453,7 @@ window.isResonatorsShow = function() {
window.isSameResonator = function(oldRes, newRes) {
if(!oldRes && !newRes) return true;
if(!oldRes || !newRes) return false;
if(typeof oldRes !== typeof newRes) return false;
if(oldRes.level !== newRes.level) return false;
if(oldRes.energyTotal !== newRes.energyTotal) return false;
@ -510,7 +516,6 @@ window.renderLink = function(ent) {
data: ent[2],
smoothFactor: 0 // doesnt work for two points anyway, so disable
});
// determine which links are very short and dont render them at all.
// in most cases this will go unnoticed, but improve rendering speed.
poly._map = window.map;
@ -537,17 +542,17 @@ window.renderLink = function(ent) {
window.renderField = function(ent) {
if(Object.keys(fields).length >= MAX_DRAWN_FIELDS)
return window.removeByGuid(ent[0]);
// assume that fields never change. If they do, they will have a
// different ID.
if(findEntityInLeaflet(fieldsLayer, fields, ent[0])) return;
var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]);
// If this already exists and the zoom level has not changed, we don't need to do anything
if(old && map.getZoom() === old.options.creationZoom) return;
var team = getTeam(ent[2]);
var reg = ent[2].capturedRegion;
var latlngs = [
[reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6],
[reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6],
[reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6]
L.latLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6),
L.latLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6),
L.latLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6)
];
var poly = L.polygon(latlngs, {
@ -556,10 +561,7 @@ window.renderField = function(ent) {
stroke: false,
clickable: false,
smoothFactor: 0, // hiding small fields will be handled below
vertices: reg,
lastUpdate: ent[1],
guid: ent[0],
data: ent[2]});
guid: ent[0]});
// determine which fields are too small to be rendered and dont
// render them, so they dont count towards the maximum fields limit.
@ -573,14 +575,65 @@ window.renderField = function(ent) {
if(!getPaddedBounds().intersects(poly.getBounds())) return;
// Curve fit equation to normalize zoom window area
var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom());
var countForMUDisplay = L.LineUtil.simplify(poly._originalPoints, FIELD_MU_DISPLAY_POINT_TOLERANCE).length
// Do nothing if zoom did not change. We need to recheck the field if the
// zoom level is different then when the field was rendered as it could
// now be appropriate or not to show an MU count
if(old) {
var layerCount = 0;
old.eachLayer(function(item) {
layerCount++;
});
// Don't do anything since we already have an MU display and we still want to
if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && countForMUDisplay > 2 && layerCount === 2) return;
// Don't do anything since we don't have an MU display and don't want to
if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && countForMUDisplay <= 2 && layerCount === 1) return;
removeByGuid(ent[0]);
}
// put both in one group, so they can be handled by the same logic.
if (areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && countForMUDisplay > 2) {
// centroid of field for placing MU count at
var centroid = [
(latlngs[0].lat + latlngs[1].lat + latlngs[2].lat)/3,
(latlngs[0].lng + latlngs[1].lng + latlngs[2].lng)/3
];
var fieldMu = L.marker(centroid, {
icon: L.divIcon({
className: 'fieldmu',
iconSize: [70,12],
html: digits(ent[2].entityScore.entityScore)
}),
clickable: false
});
var f = L.layerGroup([poly, fieldMu]);
} else {
var f = L.layerGroup([poly]);
}
f.options = {
vertices: reg,
lastUpdate: ent[1],
creationZoom: map.getZoom(),
guid: ent[0],
data: ent[2]
};
// However, LayerGroups (and FeatureGroups) dont fire add/remove
// events, thus this listener will be attached to the field. It
// doesnt matter to which element these are bound since Leaflet
// will add/remove all elements of the LayerGroup at once.
poly.on('remove', function() { delete window.fields[this.options.guid]; });
poly.on('add', function() {
// enable for debugging
if(window.fields[this.options.guid]) console.warn('duplicate field detected');
window.fields[this.options.guid] = this;
window.fields[this.options.guid] = f;
this.bringToBack();
});
poly.addTo(fieldsLayer);
f.addTo(fieldsLayer);
}
@ -601,4 +654,4 @@ window.findEntityInLeaflet = function(layerGroup, entityHash, guid) {
return false;
});
return ent;
}
}

View File

@ -17,6 +17,17 @@ window.getPlayerName = function(guid) {
return '{'+guid.slice(0, 12)+'}';
}
window.playerNameToGuid = function(playerName){
var guid = null;
$.each(Object.keys(localStorage), function(ind,key) {
if(playerName === localStorage[key]) {
guid = key;
return false;
}
});
return guid;
}
// resolves all player GUIDs that have been added to the list. Reruns
// renderPortalDetails when finished, so that then-unresolved names
// get replaced by their correct versions.

View File

@ -22,9 +22,8 @@ window.renderPortalDetails = function(guid) {
var linksText = [linkExpl('links'), linkExpl(' ↳ ' + links.incoming+'&nbsp;&nbsp;•&nbsp;&nbsp;'+links.outgoing+' ↴')];
var player = d.captured && d.captured.capturingPlayerId
? getPlayerName(d.captured.capturingPlayerId)
? '<span class="nickname">' + getPlayerName(d.captured.capturingPlayerId) + '</span>'
: null;
player = '<span class="nickname">'+player+'</span>';
var playerText = player ? ['owner', player] : null;
var time = d.captured

View File

@ -132,7 +132,7 @@ window.renderResonatorDetails = function(slot, level, nrg, dist, nick) {
var meter = '<span class="meter" title="'+inf+'">' + fill + lbar + '</span>';
}
nick = '<span class="nickname">'+nick+'</span>';
nick = nick ? '<span class="nickname">'+nick+'</span>' : null;
return [meter, nick || ''];
}

View File

@ -64,7 +64,7 @@ window.getAvgResoDist = function(d) {
sum += parseInt(reso.distanceToPortal);
resos++;
});
return sum/resos;
return resos ? sum/resos : 0;
}
window.getAttackApGain = function(d) {

View File

@ -12,12 +12,12 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) {
} else if (data.error === 'INVALID_PASSCODE') {
error = 'This passcode is invalid.';
} else {
error = 'The passcode cannot be redeemed.';
error = 'There was a problem redeeming the passcode. Try again?';
}
alert("Error: " + data.error + "\n" + error);
alert('<strong>' + data.error + '</strong>\n' + error);
} else if (data.result) {
var res_level = 0, res_count = 0;
var xmp_level = 0, xmp_count = 0;
var res_level = 0, res_count = 0;
var shield_rarity = '', shield_count = 0;
// This assumes that each passcode gives only one type of resonator/XMP/shield.
@ -30,17 +30,17 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) {
shield_count++;
}
} else if (acquired.resourceWithLevels) {
if (acquired.resourceWithLevels.resourceType === 'EMITTER_A') {
res_level = acquired.resourceWithLevels.level;
res_count++;
} else if (acquired.resourceWithLevels.resourceType === 'EMP_BURSTER') {
if (acquired.resourceWithLevels.resourceType === 'EMP_BURSTER') {
xmp_level = acquired.resourceWithLevels.level;
xmp_count++;
} else if (acquired.resourceWithLevels.resourceType === 'EMITTER_A') {
res_level = acquired.resourceWithLevels.level;
res_count++;
}
}
}
alert("Passcode redeemed!\n" + [data.result.apAward + 'AP', data.result.xmAward + 'XM', res_count + 'xL' + res_level + ' RES', xmp_count + 'xL' + xmp_level + ' XMP', shield_count + 'x' + shield_rarity + ' SHIELD'].join('/'));
alert('<strong>Passcode accepted!</strong>\n' + [data.result.apAward + 'AP', data.result.xmAward + 'XM', xmp_count + 'xL' + xmp_level + ' XMP', res_count + 'xL' + res_level + ' RES', shield_count + 'x' + shield_rarity + ' SH'].join('/'));
}
}
@ -49,6 +49,19 @@ window.setupRedeem = function() {
if((e.keyCode ? e.keyCode : e.which) != 13) return;
var data = {passcode: $(this).val()};
window.postAjax('redeemReward', data, window.handleRedeemResponse,
function() { alert('The HTTP request failed. Either your code is invalid or their servers are down. No way to tell.'); });
function(response) {
var extra = '';
if (response && response.status) {
if (response.status === 429) {
extra = 'You have been rate-limited by the server. Wait a bit and try again.';
} else {
extra = 'The server indicated an error.';
}
extra += '\nResponse: HTTP <a href="http://httpstatus.es/' + response.status + '" alt="HTTP ' + response.status + '">' + response.status + '</a>.';
} else {
extra = 'No status code was returned.';
}
alert('<strong>The HTTP request failed.</strong> ' + extra);
});
});
}

View File

@ -298,3 +298,8 @@ window.convertTextToTableMagic = function(text) {
table += '</table>';
return table;
}
// Given 3 sets of points in an array[3]{lat, lng} returns the area of the triangle
window.calcTriArea = function(p) {
return Math.abs((p[0].lat*(p[1].lng-p[2].lng)+p[1].lat*(p[2].lng-p[0].lng)+p[2].lat*(p[0].lng-p[1].lng))/2);
}

View File

@ -67,7 +67,7 @@ document.getElementsByTagName('head')[0].innerHTML = ''
+ '<style>@@INCLUDESTRING:external/leaflet.css@@</style>'
// this navigator check is also used in code/smartphone.js
+ (navigator.userAgent.match(/Android.*Mobile/)
? + '<style>@@INCLUDESTRING:mobile/smartphone.css@@</style>'
? '<style>@@INCLUDESTRING:mobile/smartphone.css@@</style>'
: '')
+ '<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Coda"/>';
@ -149,6 +149,10 @@ window.MAX_DRAWN_LINKS = 400;
window.MAX_DRAWN_FIELDS = 200;
// Minimum zoom level resonator will display
window.RESONATOR_DISPLAY_ZOOM_LEVEL = 17;
// Minimum area to zoom ratio that field MU's will display
window.FIELD_MU_DISPLAY_AREA_ZOOM_RATIO = 0.001;
// Point tolerance for displaying MU's
window.FIELD_MU_DISPLAY_POINT_TOLERANCE = 60
window.COLOR_SELECTED_PORTAL = '#f00';
window.COLORS = ['#FFCE00', '#0088FF', '#03DC03']; // none, res, enl
@ -188,7 +192,9 @@ window.DESTROY_FIELD = 750; //AP for destroying field
window.CAPTURE_PORTAL = 500; //AP for capturing a portal
window.DEPLOY_RESONATOR = 125; //AP for deploying a resonator
window.COMPLETION_BONUS = 250; //AP for deploying all resonators on portal
window.UPGRADE_ANOTHERS_RESONATOR = 65; //AP for upgrading another's resonator
window.MAX_PORTAL_LEVEL = 8;
window.MAX_RESO_PER_PLAYER = [0, 8, 4, 4, 4, 2, 2, 1, 1];
// OTHER MORE-OR-LESS CONSTANTS //////////////////////////////////////
window.TEAM_NONE = 0;

View File

@ -18,6 +18,8 @@ Available Plugins
- [**Render Limit Increase**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/render-limit-increase.user.js) increases render limits. Good for high density areas (e.g. London, UK) and faster PCs.
- [**Resonator Display Zoom Level Decrease**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/resonator-display-zoom-level-decrease.user.js) Resonator start displaying earlier.
- [**Resonator Energy in Portal Detail**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/reso-energy-pct-in-portal-detail.user.js) Resonator energy in percent is displayed in the portal detals.
- [**Scale Bar**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scale-bar.user.js) Shows a scale bar in the top left corner. [View screenshot](http://breunigs.github.com/ingress-intel-total-conversion/scre
enshots/plugin_scale_bar.png)
- [**Show Portal Address**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/show-address.user.js) Shows portal address in the side panel.
### available only with the development version

View File

@ -1,7 +1,7 @@
// ==UserScript==
// @id iitc-plugin-guess-player-levels@breunigs
// @name iitc: guess player level
// @version 0.2.1
// @version 0.3
// @namespace https://github.com/breunigs/ingress-intel-total-conversion
// @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/guess-player-levels.user.js
// @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/guess-player-levels.user.js
@ -92,19 +92,30 @@ window.plugin.guessPlayerLevels.guess = function() {
var namesR = plugin.guessPlayerLevels.sort(playersRes);
var namesE = plugin.guessPlayerLevels.sort(playersEnl);
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';
s += lineR + '\t\t' + lineE + '\n';
if(!isNaN(parseInt(lvlE)))
totallvlE += parseInt(lvlE);
s += '\n'+lineR + '\t' + lineE + '\n';
}
s += '\nTotal level :\t'+totallvlR+'\tTotal level :\t'+totallvlE;
s += '\nTotal player:\t'+namesR.length+'\tTotal player:\t'+namesE.length;
var averageR = 0, averageE = 0;
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);
alert(s);

View File

@ -204,9 +204,9 @@ window.plugin.playerTracker.drawData = function() {
var evtsLength = playerData.events.length;
var last = playerData.events[evtsLength-1];
var ago = plugin.playerTracker.ago;
var color = playerData.team === 'ALIENS' ? '#029C02' : '#00789C';
var cssClass = playerData.team === 'ALIENS' ? 'enl' : 'res';
var title =
'<span style="font-weight:bold; color:'+color+'">' + playerData.nick + '</span>\n'
'<span class="nickname '+ cssClass+'" style="font-weight:bold;">' + playerData.nick + '</span>\n'
+ ago(last.time, now) + ' minutes ago\n'
+ last.name;
// show previous data in tooltip

48
plugins/scale-bar.user.js Normal file
View File

@ -0,0 +1,48 @@
// ==UserScript==
// @id iitc-plugin-scale-bar@breunigs
// @name iitc: scale bar
// @version 0.1
// @namespace https://github.com/breunigs/ingress-intel-total-conversion
// @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scale-bar.user.js
// @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scale-bar.user.js
// @description shows scale bar on the map
// @include https://www.ingress.com/intel*
// @match https://www.ingress.com/intel*
// ==/UserScript==
function wrapper() {
// ensure plugin framework is there, even if iitc is not yet loaded
if(typeof window.plugin !== 'function') window.plugin = function() {};
// PLUGIN START ////////////////////////////////////////////////////////
// use own namespace for plugin
window.plugin.scaleBar = function() {};
window.plugin.scaleBar.setup = function() {
$('head').append('<style>.leaflet-control-scale { position: absolute; top: 2px; left: 40px; } </style>');
// Before you ask: yes, I explicitely turned off imperial units. Imperial units
// are worse than Internet Explorer 6 whirring fans combined. Upgrade to the metric
// system already.
window.map.addControl(new L.Control.Scale({position: 'topleft', imperial: false}));
};
var setup = window.plugin.scaleBar.setup;
// PLUGIN END //////////////////////////////////////////////////////////
if(window.iitcLoaded && typeof setup === 'function') {
setup();
} else {
if(window.bootPlugins)
window.bootPlugins.push(setup);
else
window.bootPlugins = [setup];
}
} // wrapper end
// inject code into site context
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ wrapper +')();'));
(document.body || document.head || document.documentElement).appendChild(script);

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -93,6 +93,15 @@ a:hover {
width: 0;
}
/* field mu count */
.fieldmu {
color: #FFCE00;
font-size:13px;
font-family: "coda",arial,helvetica,sans-serif; /*override leaflet-container */
text-align: center;
text-shadow: 0 0 0.2em black, 0 0 0.2em black, 0 0 0.2em black;
}
/* chat ***************************************************************/
@ -670,15 +679,18 @@ aside {
max-width: 300px;
position: absolute;
z-index: 9999;
background-color: #fff;
border: 1px solid #ccc;
color: #222;
background-color: rgba(8, 48, 78, 0.9);
border: 1px solid #20A8B1;
color: #eee;
font: 13px/15px "Helvetica Neue", Arial, Helvetica, sans-serif;
padding: 2px 4px;
}
.ui-tooltip, .ui-dialog a {
color: #FFCE00;
}
.ui-dialog {
border: 1px solid #0F0F0F;
padding: 0;
border-radius: 2px;
}
@ -706,23 +718,26 @@ aside {
max-width: 700px !important;
}
.ui-dialog a {
color: #0000ca;
}
.ui-dialog-buttonpane {
background: #F2F2F2;
padding: 12px;
border-top: 1px solid #E6E6E6;
border-top: 1px solid #20A8B1;
}
.ui-dialog-buttonset {
text-align: right;
}
.ui-dialog-buttonset button {
.ui-dialog-buttonset button,
.ui-dialog-content button {
padding: 2px;
min-width: 80px;
color: #FFCE00;
border: 1px solid #FFCE00;
background-color: rgba(8, 48, 78, 0.9);
}
.ui-dialog-buttonset button:hover {
text-decoration: underline;
}
td {