Merge branch 'release_20dec' into release

This commit is contained in:
Jon Atkins 2013-12-21 19:25:51 +00:00
commit 606de6a384
237 changed files with 1854 additions and 2092 deletions

View File

@ -1,6 +1,19 @@
default:
default: mkdefault
local: mklocal
mobile: mkmobile
mkdefault:
./build.py
mklocal:
./build.py local
mkmobile:
./build.py mobile
adb install -r build/mobile/IITC_Mobile-debug.apk
adb shell am start -n com.cradle.iitc_mobile/com.cradle.iitc_mobile.IITC_Mobile
clean:
ant -f mobile/build.xml clean

BIN
assets/prefer-iitc.psd Normal file

Binary file not shown.

View File

@ -289,6 +289,7 @@ if buildMobile:
if retcode != 0:
print ("Error: mobile app failed to build. ant returned %d" % retcode)
exit(1) # ant may return 256, but python seems to allow only values <256
else:
shutil.copy("mobile/bin/IITC_Mobile-%s.apk" % buildMobile, os.path.join(outDir,"IITC_Mobile-%s.apk" % buildMobile) )

View File

@ -20,7 +20,8 @@ window.artifact.setup = function() {
addResumeFunction(artifact.idleResume);
artifact.requestData();
// move the initial data request onto a very short timer. prevents thrown exceptions causing IITC boot failures
setTimeout (artifact.requestData, 1);
artifact._layer = new L.LayerGroup();
addLayerGroup ('Artifacts (Jarvis shards)', artifact._layer, true);
@ -246,7 +247,10 @@ window.artifact.showArtifactList = function() {
}
if (data[type].fragments) {
row += '<span class="fragments">Shard: #'+data[type].fragments.join(', #')+'</span> ';
if (data[type].target) {
row += '<br>';
}
row += '<span class="fragments'+(data[type].target?' '+TEAM_TO_CSS[data[type].target]:'')+'">Shard: #'+data[type].fragments.join(', #')+'</span> ';
sortVal = Math.min.apply(null, data[type].fragments); // use min shard number at portal as sort key
}

View File

@ -106,7 +106,7 @@ window.chat.genPostData = function(isFaction, storageHash, getOlderMsgs) {
// Currently this edge case is not handled. Lets see if this is a
// problem in crowded areas.
$.extend(data, {minTimestampMs: min});
// when requesting with an acutal minimum timestamp, request oldest rather than newest first.
// when requesting with an actual minimum timestamp, request oldest rather than newest first.
// this matches the stock intel site, and ensures no gaps when continuing after an extended idle period
if (min > -1) $.extend(data, {ascendingTimestampOrder: true});
}
@ -228,12 +228,12 @@ window.chat.renderCompact = function(oldMsgsWereAdded) {
$.each(chat._public.data, function(guid, entry) {
// skip player msgs
if(!entry[1]) return true;
var pguid = entry[3];
var nick = entry[3];
// ignore if player has newer data
if(data[pguid] && data[pguid][0] > entry[0]) return true;
data[pguid] = entry;
if(data[nick] && data[nick][0] > entry[0]) return true;
data[nick] = entry;
});
// data keys are now player guids instead of message guids. However,
// data keys are now player nicks instead of message guids. However,
// it is all the same to renderData.
chat.renderData(data, 'chatcompact', oldMsgsWereAdded);
}
@ -350,7 +350,7 @@ window.chat.writeDataToHash = function(newData, storageHash, isPublicChannel, is
// format: timestamp, autogenerated, HTML message
storageHash.data[json[0]] = [json[1], auto, chat.renderMsg(msg, nick, time, team, msgToPlayer, systemNarrowcast)];
storageHash.data[json[0]] = [json[1], auto, chat.renderMsg(msg, nick, time, team, msgToPlayer, systemNarrowcast), nick];
});
}

View File

@ -6,7 +6,8 @@ window.updateGameScoreFailCount = 0;
window.updateGameScore = function(data) {
if(!data) {
window.postAjax('getGameScore', {}, window.updateGameScore);
// move the postAjax call onto a very short timer. this way, if it throws an exception, it won't prevent IITC booting
setTimeout (function() { window.postAjax('getGameScore', {}, window.updateGameScore); }, 1);
return;
}

View File

@ -50,6 +50,10 @@
// iitcLoaded: called after IITC and all plugins loaded
// portalDetailLoaded: called when a request to load full portal detail
// completes. guid, success, details parameters
// paneChanged called when the current pane has changed. On desktop,
// this only selects the current chat pane; on mobile, it
// also switches between map, info and other panes defined
// by plugins
window._hooks = {}
window.VALID_HOOKS = [
@ -60,30 +64,32 @@ window.VALID_HOOKS = [
'publicChatDataAvailable', 'factionChatDataAvailable',
'requestFinished', 'nicknameClicked',
'geoSearch', 'iitcLoaded',
'portalDetailLoaded'];
'portalDetailLoaded', 'paneChanged'];
window.runHooks = function(event, data) {
if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event);
if(!_hooks[event]) return true;
var interupted = false;
var interrupted = false;
$.each(_hooks[event], function(ind, callback) {
try {
if (callback(data) === false) {
interupted = true;
interrupted = true;
return false; //break from $.each
}
} catch(err) {
console.error('error running hook '+event+', error: '+err);
debugger;
}
});
return !interupted;
return !interrupted;
}
window.addHook = function(event, callback) {
if(VALID_HOOKS.indexOf(event) === -1) {
console.error('addHook: Unknown event type: ' + event + ' - ignoring');
debugger;
return;
}

View File

@ -6,7 +6,7 @@
// tile and a quadkey. Both the bounds and the quadkey are “somewhat”
// required to get complete data.
//
// Convertion functions courtesy of
// Conversion functions courtesy of
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

View File

@ -470,7 +470,7 @@ window.Render.prototype.addPortalToMapLayer = function(portal) {
this.portalClusters[cid].push(portal.options.guid);
// now, at this point, we could match the above re-clustr code - sorting, and adding/removing as necessary
// now, at this point, we could match the above re-cluster code - sorting, and adding/removing as necessary
// however, it won't make a lot of visible difference compared to just pushing to the end of the list, then
// adding to the visible layer if the list is below the limit
if (this.portalClusters[cid].length < this.CLUSTER_PORTAL_LIMIT || portal.options.guid == selectedPortal || artifact.isInterestingPortal(portal.options.guid)) {

View File

@ -16,8 +16,9 @@ window.MapDataRequest = function() {
// no more than this many requests in parallel. stock site seems to rely on browser limits (6, usually), sending
// all requests at once. using our own queue limit ensures that other requests (e.g. chat) don't get postponed for too long
this.MAX_REQUESTS = 6;
// many requests at once.
// using our own queue limit ensures that other requests (e.g. chat, portal details) don't get delayed
this.MAX_REQUESTS = 5;
// no more than this many tiles in one request
// as of 2013-11-11, or possibly the release before that, the stock site was changed to only request four tiles at a time
@ -28,7 +29,7 @@ window.MapDataRequest = function() {
this.MIN_TILES_PER_REQUEST = 4;
// number of times to retry a tile after a 'bad' error (i.e. not a timeout)
this.MAX_TILE_RETRIES = 1;
this.MAX_TILE_RETRIES = 2;
// refresh timers
this.MOVE_REFRESH = 1; //time, after a map move (pan/zoom) before starting the refresh processing

View File

@ -12,50 +12,58 @@
;(function(){
var requestParameterMunges = [
// obsolete munge sets (they don't have some of the new parameters) deleted
// all old munge sets deleted - there's no sign that any old ones will become active again
// set 10 - 2013-11-27
{
'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO
'dashboard.getGameScore': '4oid643d9zc168hs', // GET_GAME_SCORE
'dashboard.getPaginatedPlexts': 's1msyywq51ntudpe', // GET_PAGINATED_PLEXTS
'dashboard.getThinnedEntities': '4467ff9bgxxe4csa', // GET_THINNED_ENTITIES
'dashboard.getPortalDetails': 'c00thnhf1yp3z6mn', // GET_PORTAL_DETAILS
'dashboard.redeemReward': '66l9ivg39ygfqqjm', // REDEEM_REWARD
'dashboard.sendInviteEmail': 'cgb7hi5hglv0xx8k', // SEND_INVITE_EMAIL
'dashboard.sendPlext': 'etn9xq7brd6947kq', // SEND_PLEXT
// common parameters
method: 'yyngyttbmmbuvdpa',
version: 'avz401t36lzrapis',
version_parameter: 'c5d0a5d608f729a1232bebdc12fb86ba5fb6c43f',
// GET_THINNED_ENTITIES
quadKeys: '1mpmxz2yun22rwnn',
// GET_PAGINATED_PLEXTS
desiredNumItems: 'nzd23jqm9k1cnnij',
minLatE6: '0dod6onpa1s4fezp',
minLngE6: 'soass3t7mm7anneo',
maxLatE6: 'cvarmr3o00ngylo1',
maxLngE6: 'udzwnlx07hzd3bfo',
minTimestampMs: '9iiiks138gkf8xho',
maxTimestampMs: '94wm0u3sc3sgzq7x',
chatTab: 'tqfj4a3okzn5v5o1',
ascendingTimestampOrder: '5jv1m90sq35u6utq',
// SEND_PLEXT
message: '8exta9k7y8huhqmc',
latE6: 'kqek161gza3kjcry',
lngE6: '3dlxsqrjj2vcmhbc',
// chatTab: 'efaznrayv5n3jxs0', //guessed parameter name - only seen munged
// GET_PORTAL_DETAILS
guid: 'seg6ohxgnqf9xu9w',
// SEND_INVITE_EMAIL
inviteeEmailAddress: '8exta9k7y8huhqmc',
},
// the current munge set auto-detection code is working very well. as any site update that breaks that detection
// code will also, almost certainly, change the munges in use, it seems pointless keeping this set up to date by hand
// at this time. If that auto-detection breaks, it may be easier to quicky add a munge set by hand than update
// the regular expressions, so the list-based code remains available for the future
// // set 11 - 2013-12-06
// {
// 'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO
// 'dashboard.getGameScore': '4oid643d9zc168hs', // GET_GAME_SCORE
// 'dashboard.getPaginatedPlexts': 's1msyywq51ntudpe', // GET_PAGINATED_PLEXTS
// 'dashboard.getThinnedEntities': '4467ff9bgxxe4csa', // GET_THINNED_ENTITIES
// 'dashboard.getPortalDetails': 'c00thnhf1yp3z6mn', // GET_PORTAL_DETAILS
// 'dashboard.redeemReward': 'ivshfv9zvyfxyqcd', // REDEEM_REWARD
// 'dashboard.sendInviteEmail': '1rsx15vc0m8wwdax', // SEND_INVITE_EMAIL
// 'dashboard.sendPlext': 'tods2imd0xcfsug6', // SEND_PLEXT
//
// // common parameters
// method: '0wvzluo8av4sk17f',
// version: 'paeh4g353xu06kfg',
// version_parameter: '4acc1e3230c3fd66be3422c0df8dc637336bbd7c',
//
// // GET_THINNED_ENTITIES
// quadKeys: 'ilgv0w4dlldky1yh',
//
// // GET_PORTAL_DETAILS
// guid: '7o8tzmj6oxz1n5w3',
//
// // REDEEM_REWARD
// passcode: 'passcode', // no munging on this parameter
//
// // SEND_INVITE_EMAIL
// inviteeEmailAddress: 'p4rwszdfovuwfdgp',
//
// // GET_PAGINATED_PLEXTS
// desiredNumItems: 'kxsbuvc90l6f40xn',
// minLatE6: 'llizye3i5dbapxac',
// minLngE6: 'w01zpiba1mn5tsab',
// maxLatE6: 'd5phhqzj2tbsq599',
// maxLngE6: 'avq5srnvg431aehn',
// minTimestampMs: 'mhsav5by25wi4s46',
// maxTimestampMs: 'hpu7l8h7eccwytyt',
// chatTab: 'q9343nem7hs1v37b',
// ascendingTimestampOrder: '7pc5c9ggh03pig1b',
//
// // SEND_PLEXT
// message: '8exta9k7y8huhqmc',
// latE6: '7ffwyf3zd2yf8xam',
// lngE6: 'n7ewiach2v22iy20',
//// chatTab: 'q9343nem7hs1v37b', // duplicate from GET_PAGINATED_PLEXTS
//
// },
];

View File

@ -3,6 +3,8 @@
window.show = function(id) {
window.hideall();
runHooks("paneChanged", id);
switch(id) {
case 'full':
window.chat.show('full');
@ -27,9 +29,6 @@ window.show = function(id) {
case 'info':
window.smartphone.sideButton.click();
break;
default:
window.smartphone.mapButton.click();
break;
}
if (typeof android !== 'undefined' && android && android.switchToPane) {

View File

@ -21,6 +21,11 @@ window.getPortalLinks = function(guid) {
return links;
}
window.getPortalLinksCount = function(guid) {
var links = getPortalLinks(guid);
return links.in.length+links.out.length;
}
// search through the fields for all that reference a portal
window.getPortalFields = function(guid) {
@ -40,6 +45,11 @@ window.getPortalFields = function(guid) {
return fields;
}
window.getPortalFieldsCount = function(guid) {
var fields = getPortalFields(guid);
return fields.length;
}
// find the lat/lon for a portal, using any and all available data
// (we have the list of portals, the cached portal details, plus links and fields as sources of portal locations)
@ -79,3 +89,48 @@ window.findPortalLatLng = function(guid) {
// no luck finding portal lat/lng
return undefined;
}
// get the AP gains from a portal, based only on the brief summary data from portals, links and fields
// not entirely accurate - but available for all portals on the screen
window.getPortalApGain = function(guid) {
var p = window.portals[guid];
if (p) {
var data = p.options.data;
var linkCount = getPortalLinksCount(guid);
var fieldCount = getPortalFieldsCount(guid);
var result = portalApGainMaths(data.resCount, linkCount, fieldCount);
return result;
}
return undefined;
}
// given counts of resonators, links and fields, calculate the available AP
// doesn't take account AP for resonator upgrades or AP for adding mods
window.portalApGainMaths = function(resCount, linkCount, fieldCount) {
var deployAp = (8-resCount)*DEPLOY_RESONATOR;
if (resCount == 0) deployAp += CAPTURE_PORTAL;
if (resCount != 8) deployAp += COMPLETION_BONUS;
// there could also be AP for upgrading existing resonators, and for deploying mods - but we don't have data for that
var friendlyAp = deployAp;
var destroyResoAp = resCount*DESTROY_RESONATOR;
var destroyLinkAp = linkCount*DESTROY_LINK;
var destroyFieldAp = fieldCount*DESTROY_FIELD;
var captureAp = CAPTURE_PORTAL + 8 * DEPLOY_RESONATOR + COMPLETION_BONUS;
var destroyAp = destroyResoAp+destroyLinkAp+destroyFieldAp;
var enemyAp = destroyAp+captureAp;
return {
friendlyAp: friendlyAp,
enemyAp: enemyAp,
destroyAp: destroyAp,
destroyResoAp: destroyResoAp,
captureAp: captureAp
}
}

View File

@ -1,5 +1,5 @@
/// PORTAL DETAIL //////////////////////////////////////
// code to retrieve the new potal detail data from the servers
// code to retrieve the new portal detail data from the servers
// NOTE: the API for portal detailed information is NOT FINAL
// this is a temporary measure to get things working again after a major change to the intel map
@ -54,6 +54,6 @@ window.portalDetail.request = function(guid) {
})(); // anonumous wrapper function end
})(); // anonymous wrapper function end

View File

@ -5,7 +5,7 @@
window.renderPortalDetails = function(guid) {
selectPortal(window.portals[guid] ? guid : null);
if (!portalDetail.isFresh(guid)) {
if (guid && !portalDetail.isFresh(guid)) {
portalDetail.request(guid);
}
@ -26,6 +26,11 @@ window.renderPortalDetails = function(guid) {
var data = portal.options.data;
var details = portalDetail.get(guid);
// details and data can get out of sync. if we have details, construct a matching 'data'
if (details) {
data = getPortalSummaryData(details);
}
var modDetails = details ? '<div class="mods">'+getModDetails(details)+'</div>' : '';
var miscDetails = details ? getPortalMiscDetails(guid,details) : '';
@ -78,8 +83,8 @@ window.renderPortalDetails = function(guid) {
}
// portal level. start with basic data - then extend with fractional info in tooltip if available
var levelInt = data ? data.level : getPortalLevel(details);
var levelDetails = data.level;
var levelInt = portal.options.level;
var levelDetails = portal.options.level;
if (details) {
levelDetails = getPortalLevel(details);
if(levelDetails != 8) {
@ -109,7 +114,7 @@ window.renderPortalDetails = function(guid) {
} else {
// non-android - a permalink for the portal
var permaHtml = $('<div>').html( $('<a>').attr({href:permalinkUrl, target:'_blank', title:'Create a URL link to this portal'}).text('Portal link') ).html();
var permaHtml = $('<div>').html( $('<a>').attr({href:permalinkUrl, title:'Create a URL link to this portal'}).text('Portal link') ).html();
linkDetails.push ( '<aside>'+permaHtml+'</aside>' );
// and a map link popup dialog
@ -178,7 +183,9 @@ window.getPortalMiscDetails = function(guid,d) {
: null;
var sinceText = time ? ['since', time] : null;
var linkedFields = ['fields', d.portalV2.linkedFields ? d.portalV2.linkedFields.length : 0];
var fieldCount = getPortalFieldsCount(guid);
var linkedFields = ['fields', fieldCount];
// collect and html-ify random data
var randDetailsData = [];
@ -189,7 +196,7 @@ window.getPortalMiscDetails = function(guid,d) {
randDetailsData.push (
getRangeText(d), getEnergyText(d),
linksText, getAvgResoDistText(d),
linkedFields, getAttackApGainText(d),
linkedFields, getAttackApGainText(d,fieldCount),
getHackDetailsText(d), getMitigationText(d)
);

View File

@ -193,8 +193,13 @@ window.getResonatorDetails = function(d) {
// slot: which slot this resonator occupies. Starts with 0 (east) and
// rotates clockwise. So, last one is 7 (southeast).
window.renderResonatorDetails = function(slot, level, nrg, dist, nick) {
if(OCTANTS[slot] === 'N')
var className = 'meter north';
else
var className = 'meter';
if(level === 0) {
var meter = '<span class="meter" title="octant:\t' + OCTANTS[slot] + ' ' + OCTANTS_ARROW[slot] + '"></span>';
var meter = '<span class="' + className + '" title="octant:\t' + OCTANTS[slot] + ' ' + OCTANTS_ARROW[slot] + '"></span>';
} else {
var max = RESO_NRG[level];
var fillGrade = nrg/max*100;
@ -209,19 +214,19 @@ window.renderResonatorDetails = function(slot, level, nrg, dist, nick) {
var color = (level < 3 ? "#9900FF" : "#FFFFFF");
var lbar = '<span class="meter-level" style="color: ' + color + ';"> ' + level + ' </span>';
var lbar = '<span class="meter-level" style="color: ' + color + ';"> L ' + level + ' </span>';
var fill = '<span style="'+style+'"></span>';
var meter = '<span class="meter" title="'+inf+'">' + fill + lbar + '</span>';
var meter = '<span class="' + className + '" title="'+inf+'">' + fill + lbar + '</span>';
}
nick = nick ? '<span class="nickname">'+nick+'</span>' : null;
return [meter, nick || ''];
}
// calculate AP gain from destroying portal and then capturing it by deploying resonators
window.getAttackApGainText = function(d) {
var breakdown = getAttackApGain(d);
window.getAttackApGainText = function(d,fieldCount) {
var breakdown = getAttackApGain(d,fieldCount);
var totalGain = breakdown.enemyAp;
function tt(text) {

View File

@ -68,22 +68,23 @@ window.getLinkAmpRangeBoost = function(d) {
// (at the time of writing, only rare link amps have been seen in the wild, so there's a little guesswork at how
// the stats work and combine - jon 2013-06-26)
// link amps scale: first is full, second half, the last two a quarter
var scale = [1.0, 0.5, 0.25, 0.25];
// link amps scale: first is full, second a quarter, the last two an eigth
var scale = [1.0, 0.25, 0.125, 0.125];
var boost = 1.0; // initial boost is 1.0 (i.e. no boost over standard range)
var boost = 0.0; // initial boost is 0.0 (i.e. no boost over standard range)
var count = 0;
$.each(d.portalV2.linkedModArray, function(ind, mod) {
if(mod && mod.type === 'LINK_AMPLIFIER' && mod.stats && mod.stats.LINK_RANGE_MULTIPLIER) {
var linkAmps = getPortalModsByType(d, 'LINK_AMPLIFIER');
$.each(linkAmps, function(ind, mod) {
// link amp stat LINK_RANGE_MULTIPLIER is 2000 for rare, and gives 2x boost to the range
// and very-rare is 7000 and gives 7x the range
var baseMultiplier = mod.stats.LINK_RANGE_MULTIPLIER/1000;
boost += (baseMultiplier-1)*scale[count];
boost += baseMultiplier*scale[count];
count++;
}
});
return boost;
return (count > 0) ? boost : 1.0;
}
@ -99,7 +100,9 @@ window.getAvgResoDist = function(d) {
return resos ? sum/resos : 0;
}
window.getAttackApGain = function(d) {
window.getAttackApGain = function(d,fieldCount) {
if (!fieldCount) fieldCount = 0;
var resoCount = 0;
var maxResonators = MAX_RESO_PER_PLAYER.slice(0);
var curResonators = [ 0, 0, 0, 0, 0, 0, 0, 0, 0];
@ -123,7 +126,7 @@ window.getAttackApGain = function(d) {
});
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;
@ -307,4 +310,30 @@ window.getPortalHackDetails = function(d) {
return {cooldown: cooldownTime, hacks: numHacks, burnout: cooldownTime*(numHacks-1)};
}
// given a detailed portal structure, return summary portal data, as seen in the map tile data
window.getPortalSummaryData = function(d) {
// NOTE: the summary data reports unclaimed portals as level 1 - not zero as elsewhere in IITC
var level = d.controllingTeam.team == "NEUTRAL" ? 1 : parseInt(getPortalLevel(d));
var resCount = 0;
if (d.resonatorArray && d.resonatorArray.resonators) {
for (var x in d.resonatorArray.resonators) {
if (d.resonatorArray.resonators[x]) resCount++;
}
}
var maxEnergy = getTotalPortalEnergy(d);
var curEnergy = getCurrentPortalEnergy(d);
var health = maxEnergy>0 ? parseInt(curEnergy/maxEnergy*100) : 0;
return {
level: level,
title: d.portalV2.descriptiveText.TITLE,
image: d.imageByUrl && d.imageByUrl.imageUrl,
resCount: resCount,
latE6: d.locationE6.latE6,
health: health,
team: d.controllingTeam.team,
lngE6: d.locationE6.lngE6,
type: 'portal'
};
}

View File

@ -66,24 +66,36 @@ window.runOnSmartphonesBeforeBoot = function() {
}
window.smartphoneInfo = function(data) {
var d = data.portalDetails;
var lvl = Math.floor(getPortalLevel(d));
if(lvl == 0)
var t = '<span class="portallevel">L' + lvl + '</span>';
var guid = data.selectedPortalGuid;
if(!window.portals[guid]) return;
var data = window.portals[selectedPortal].options.data;
var details = window.portalDetail.get(guid);
var lvl = data.level;
if(data.team === "NEUTRAL")
var t = '<span class="portallevel">L0</span>';
else
var t = '<span class="portallevel" style="background: '+COLORS_LVL[lvl]+';">L' + lvl + '</span>';
var percentage = '0%';
var totalEnergy = getTotalPortalEnergy(d);
if(getTotalPortalEnergy(d) > 0) {
percentage = Math.floor((getCurrentPortalEnergy(d) / getTotalPortalEnergy(d) * 100)) + '%';
}
t += ' ' + percentage + ' ';
t += d.portalV2.descriptiveText.TITLE;
var percentage = data.health;
if(details) {
var totalEnergy = getTotalPortalEnergy(details);
if(getTotalPortalEnergy(details) > 0) {
percentage = Math.floor(getCurrentPortalEnergy(details) / totalEnergy * 100);
}
}
t += ' ' + percentage + '% ';
t += data.title;
if(details) {
var l,v,max,perc;
for(var i=0;i<8;i++)
{
var reso = d.resonatorArray.resonators[i];
var className = TEAM_TO_CSS[getTeam(details)];
if(OCTANTS[i] === 'N')
className += ' north'
var reso = details.resonatorArray.resonators[i];
if(reso) {
l = parseInt(reso.level);
v = parseInt(reso.energyTotal);
@ -97,10 +109,11 @@ window.smartphoneInfo = function(data) {
perc = 0;
}
t += '<div class="resonator '+TEAM_TO_CSS[getTeam(d)]+'" style="border-top-color: '+COLORS_LVL[l]+';left: '+(100*i/8.0)+'%;">';
t += '<div class="resonator '+className+'" style="border-top-color: '+COLORS_LVL[l]+';left: '+(100*i/8.0)+'%;">';
t += '<div class="filllevel" style="width:'+perc+'%;"></div>';
t += '</div>'
}
}
$('#mobileinfo').html(t);
}
@ -113,7 +126,7 @@ window.runOnSmartphonesAfterBoot = function() {
// add a div/hook for updating mobile info
$('#updatestatus').prepend('<div id="mobileinfo" onclick="show(\'info\')"></div>');
window.addHook('portalDetailsUpdated', window.smartphoneInfo);
window.addHook('portalSelected', window.smartphoneInfo);
// init msg of status bar. hint for the user that a tap leads to the info screen
$('#mobileinfo').html('<div style="text-align: center"><b>tap here for info screen</b></div>');
@ -157,3 +170,9 @@ window.runOnSmartphonesAfterBoot = function() {
window.MAX_DRAWN_LINKS = 200;
window.MAX_DRAWN_FIELDS = 100;
}
window.useAndroidPanes = function() {
// isSmartphone is important to disable panes in desktop mode
return (typeof android !== 'undefined' && android && android.addPane && window.isSmartphone());
}

View File

@ -122,7 +122,9 @@ window.convertCookieToLocalStorage = function(name) {
// add thousand separators to given number.
// http://stackoverflow.com/a/1990590/1684530 by Doug Neiner.
window.digits = function(d) {
return (d+"").replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1 ");
// U+2009 - Thin Space. Recommended for use as a thousands separator...
// https://en.wikipedia.org/wiki/Space_(punctuation)#Table_of_spaces
return (d+"").replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1&#8201;");
}
@ -267,11 +269,11 @@ window.androidCopy = function(text) {
}
window.androidPermalink = function() {
if(typeof android === 'undefined' || !android || !android.copy)
if(typeof android === 'undefined' || !android || !android.intentPosLink)
return true; // i.e. execute other actions
var center = map.getCenter();
android.intentPosLink(center.lat, center.lng, map.getZoom(), "Intel Map", false);
android.intentPosLink(center.lat, center.lng, map.getZoom(), "Selected map view", false);
return false;
}

View File

@ -35,47 +35,53 @@ Modified by qnstie 2013-07-17 to maintain compatibility with Leaflet.draw
});
}
function geodesicConvertLine(startLatlng, endLatlng, convertedPoints) {
var i,
R = 6378137, // earth radius in meters (doesn't have to be exact)
maxlength = 5000, // meters before splitting
d2r = L.LatLng.DEG_TO_RAD,
r2d = L.LatLng.RAD_TO_DEG,
lat1, lat2, lng1, lng2, dLng, d, segments,
f, A, B, x, y, z, fLat, fLng;
// alternative geodesic line intermediate points function
// as north/south lines have very little curvature in the projection, we cam use longitude (east/west) seperation
// to calculate intermediate points. hopeefully this will avoid the rounding issues seen in the full intermediate
// points code that have been seen
function geodesicConvertLine(startLatLng, endLatLng, convertedPoints) {
var R = 6378137; // earth radius in meters (doesn't have to be exact)
var d2r = L.LatLng.DEG_TO_RAD;
var r2d = L.LatLng.RAD_TO_DEG;
dLng = (endLatlng.lng - startLatlng.lng) * d2r;
lat1 = startLatlng.lat * d2r;
lat2 = endLatlng.lat * d2r;
lng1 = startLatlng.lng * d2r;
lng2 = endLatlng.lng * d2r;
// maths based on http://williams.best.vwh.net/avform.htm#Int
// http://en.wikipedia.org/wiki/Great-circle_distance
d = Math.atan2(Math.sqrt( Math.pow(Math.cos(lat2) * Math.sin(dLng), 2) + Math.pow(Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLng), 2) ), Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(dLng));
var lat1 = startLatLng.lat * d2r;
var lat2 = endLatLng.lat * d2r;
var lng1 = startLatLng.lng * d2r;
var lng2 = endLatLng.lng * d2r;
segments = Math.ceil(d * R / maxlength);
// loop starts at 1 - we don't add the very first point
// loop ends before 'segments' is reached - we don't add the very last point here but outside the loop
// (this was to fix a bug - https://github.com/jonatkins/ingress-intel-total-conversion/issues/471
// rounding errors? maths bug? not sure - but it solves the issue! and is a slight optimisation)
for (i = 1; i < segments; i++) {
// http://williams.best.vwh.net/avform.htm#Intermediate
// modified to handle longitude above +-180 degrees
f = i / segments;
A = Math.sin((1-f)*d) / Math.sin(d);
B = Math.sin(f*d) / Math.sin(d);
x = A * Math.cos(lat1) * Math.cos(0) + B * Math.cos(lat2) * Math.cos(dLng);
y = A * Math.cos(lat1) * Math.sin(0) + B * Math.cos(lat2) * Math.sin(dLng);
z = A * Math.sin(lat1) + B * Math.sin(lat2);
fLat = r2d * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
fLng = r2d * (Math.atan2(y, x)+lng1);
var dLng = lng2-lng1;
convertedPoints.push(L.latLng([fLat, fLng]));
var segments = Math.floor(Math.abs(dLng * R / 5000));
if (segments > 1) {
// pre-calculate some constant values for the loop
var sinLat1 = Math.sin(lat1);
var sinLat2 = Math.sin(lat2);
var cosLat1 = Math.cos(lat1);
var cosLat2 = Math.cos(lat2);
var sinLat1CosLat2 = sinLat1*cosLat2;
var sinLat2CosLat1 = sinLat2*cosLat1;
var cosLat1CosLat2SinDLng = cosLat1*cosLat2*Math.sin(dLng);
for (var i=1; i < segments; i++) {
var iLng = lng1+dLng*(i/segments);
var iLat = Math.atan( (sinLat1CosLat2*Math.sin(lng2-iLng) + sinLat2CosLat1*Math.sin(iLng-lng1))
/ cosLat1CosLat2SinDLng)
var point = L.latLng ( [iLat*r2d, iLng*r2d] );
convertedPoints.push(point);
}
// push the final point unmodified
convertedPoints.push(L.latLng(endLatlng));
}
convertedPoints.push(L.latLng(endLatLng));
}
L.geodesicConvertLines = function (latlngs, fill) {
if (latlngs.length == 0) {
return [];

View File

@ -7,7 +7,7 @@
var oldL = window.L,
L = {};
L.version = '0.7';
L.version = '0.7.1';
// define Leaflet for Node module pattern loaders, including Browserify
if (typeof module === 'object' && typeof module.exports === 'object') {
@ -134,21 +134,16 @@ L.Util = {
}
return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');
},
compileTemplate: function (str, data) {
// based on https://gist.github.com/padolsey/6008842
str = str.replace(/"/g, '\\\"');
str = str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
return '" + o["' + key + '"]' + (typeof data[key] === 'function' ? '(o)' : '') + ' + "';
});
// jshint evil: true
return new Function('o', 'return "' + str + '";');
},
template: function (str, data) {
var cache = L.Util._templateCache = L.Util._templateCache || {};
cache[str] = cache[str] || L.Util.compileTemplate(str, data);
return cache[str](data);
return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
var value = data[key];
if (value === undefined) {
throw new Error('No value provided for variable ' + str);
} else if (typeof value === 'function') {
value = value(data);
}
return value;
});
},
isArray: Array.isArray || function (obj) {
@ -534,7 +529,7 @@ L.Mixin.Events.fire = L.Mixin.Events.fireEvent;
doc = document.documentElement,
ie3d = ie && ('transition' in doc.style),
webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()),
webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23,
gecko3d = 'MozPerspective' in doc.style,
opera3d = 'OTransition' in doc.style,
any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d || opera3d) && !phantomjs;
@ -1070,11 +1065,6 @@ L.DomUtil = {
if (!disable3D && L.Browser.any3d) {
el.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(point);
// workaround for Android 2/3 stability (https://github.com/CloudMade/Leaflet/issues/69)
if (L.Browser.mobileWebkit3d) {
el.style.WebkitBackfaceVisibility = 'hidden';
}
} else {
el.style.left = point.x + 'px';
el.style.top = point.y + 'px';
@ -1770,6 +1760,8 @@ L.Map = L.Class.extend({
},
invalidateSize: function (options) {
if (!this._loaded) { return this; }
options = L.extend({
animate: false,
pan: true
@ -1779,8 +1771,6 @@ L.Map = L.Class.extend({
this._sizeChanged = true;
this._initialCenter = null;
if (!this._loaded) { return this; }
var newSize = this.getSize(),
oldCenter = oldSize.divideBy(2).round(),
newCenter = newSize.divideBy(2).round(),
@ -2857,11 +2847,9 @@ L.TileLayer = L.Class.extend({
/*
Chrome 20 layouts much faster with top/left (verify with timeline, frames)
Android 4 browser has display issues with top/left and requires transform instead
Android 2 browser requires top/left or tiles disappear on load or first drag
(reappear after zoom) https://github.com/CloudMade/Leaflet/issues/866
(other browsers don't currently care) - see debug/hacks/jitter.html for an example
*/
L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome || L.Browser.android23);
L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome);
this._tiles[tilePoint.x + ':' + tilePoint.y] = tile;
@ -4481,10 +4469,10 @@ L.FeatureGroup = L.LayerGroup.extend({
},
_propagateEvent: function (e) {
e = L.extend({}, e, {
e = L.extend({
layer: e.target,
target: this
});
}, e);
this.fire(e.type, e);
}
});
@ -5255,7 +5243,7 @@ L.Map.include((L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? {}
* and polylines (clipping, simplification, distances, etc.)
*/
/*jshint bitwise:false */ // allow bitwise oprations for this file
/*jshint bitwise:false */ // allow bitwise operations for this file
L.LineUtil = {
@ -5988,6 +5976,7 @@ L.CircleMarker = L.Circle.extend({
if (this._popup && this._popup._isOpen) {
this._popup.setLatLng(latlng);
}
return this;
},
setRadius: function (radius) {
@ -6769,7 +6758,7 @@ L.Draggable = L.Class.extend({
L.DomUtil.enableImageDrag();
L.DomUtil.enableTextSelection();
if (this._moved) {
if (this._moved && this._moving) {
// ensure drag is not fired after dragend
L.Util.cancelAnimFrame(this._animRequest);
@ -8903,8 +8892,8 @@ if (L.DomUtil.TRANSITION) {
L.Map.include(!L.DomUtil.TRANSITION ? {} : {
_catchTransitionEnd: function () {
if (this._animatingZoom) {
_catchTransitionEnd: function (e) {
if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) {
this._onZoomTransitionEnd();
}
},

8
external/leaflet.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
// ==UserScript==
// @id ingress-intel-total-conversion@jonatkins
// @name IITC: Ingress intel map total conversion
// @version 0.16.0.@@DATETIMEVERSION@@
// @version 0.16.1.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
@ -39,8 +39,11 @@ if(!d) {
// page doesnt have a script tag with player information.
if(document.getElementById('header_email')) {
// however, we are logged in.
setTimeout('location.reload();', 3*1000);
throw("Page doesn't have player data, but you are logged in. Reloading in 3s.");
// it used to be regularly common to get temporary 'account not enabled' messages from the intel site.
// however, this is no longer common. more common is users getting account suspended/banned - and this
// currently shows the 'not enabled' message. so it's safer to not repeatedly reload in this case
// setTimeout('location.reload();', 3*1000);
throw("Page doesn't have player data, but you are logged in.");
}
// FIXME: handle nia takedown in progress
throw("Couldn't retrieve player data. Are you logged in?");

View File

@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cradle.iitc_mobile"
android:installLocation="auto"
android:versionCode="61"
android:versionName="0.10.0">
android:versionCode="62"
android:versionName="0.10.1">
<uses-sdk
android:minSdkVersion="14"
@ -99,7 +99,7 @@
android:enabled="true"
android:excludeFromRecents="true"
android:exported="false"
android:icon="@drawable/copy"
android:icon="@drawable/ic_action_copy"
android:label="@string/activity_share_to_clipboard"
android:noHistory="false">
<intent-filter>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 638 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

View File

Before

Width:  |  Height:  |  Size: 435 B

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

View File

Before

Width:  |  Height:  |  Size: 334 B

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show More