Merge branch 'release_20dec' into release
15
Makefile
@ -1,6 +1,19 @@
|
|||||||
default:
|
default: mkdefault
|
||||||
|
|
||||||
|
local: mklocal
|
||||||
|
mobile: mkmobile
|
||||||
|
|
||||||
|
mkdefault:
|
||||||
./build.py
|
./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:
|
clean:
|
||||||
ant -f mobile/build.xml clean
|
ant -f mobile/build.xml clean
|
||||||
|
|
||||||
|
BIN
assets/prefer-iitc.psd
Normal file
1
build.py
@ -289,6 +289,7 @@ if buildMobile:
|
|||||||
|
|
||||||
if retcode != 0:
|
if retcode != 0:
|
||||||
print ("Error: mobile app failed to build. ant returned %d" % retcode)
|
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:
|
else:
|
||||||
shutil.copy("mobile/bin/IITC_Mobile-%s.apk" % buildMobile, os.path.join(outDir,"IITC_Mobile-%s.apk" % buildMobile) )
|
shutil.copy("mobile/bin/IITC_Mobile-%s.apk" % buildMobile, os.path.join(outDir,"IITC_Mobile-%s.apk" % buildMobile) )
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ window.artifact.setup = function() {
|
|||||||
|
|
||||||
addResumeFunction(artifact.idleResume);
|
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();
|
artifact._layer = new L.LayerGroup();
|
||||||
addLayerGroup ('Artifacts (Jarvis shards)', artifact._layer, true);
|
addLayerGroup ('Artifacts (Jarvis shards)', artifact._layer, true);
|
||||||
@ -246,7 +247,10 @@ window.artifact.showArtifactList = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (data[type].fragments) {
|
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
|
sortVal = Math.min.apply(null, data[type].fragments); // use min shard number at portal as sort key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
code/chat.js
@ -106,7 +106,7 @@ window.chat.genPostData = function(isFaction, storageHash, getOlderMsgs) {
|
|||||||
// Currently this edge case is not handled. Let’s see if this is a
|
// Currently this edge case is not handled. Let’s see if this is a
|
||||||
// problem in crowded areas.
|
// problem in crowded areas.
|
||||||
$.extend(data, {minTimestampMs: min});
|
$.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
|
// this matches the stock intel site, and ensures no gaps when continuing after an extended idle period
|
||||||
if (min > -1) $.extend(data, {ascendingTimestampOrder: true});
|
if (min > -1) $.extend(data, {ascendingTimestampOrder: true});
|
||||||
}
|
}
|
||||||
@ -228,12 +228,12 @@ window.chat.renderCompact = function(oldMsgsWereAdded) {
|
|||||||
$.each(chat._public.data, function(guid, entry) {
|
$.each(chat._public.data, function(guid, entry) {
|
||||||
// skip player msgs
|
// skip player msgs
|
||||||
if(!entry[1]) return true;
|
if(!entry[1]) return true;
|
||||||
var pguid = entry[3];
|
var nick = entry[3];
|
||||||
// ignore if player has newer data
|
// ignore if player has newer data
|
||||||
if(data[pguid] && data[pguid][0] > entry[0]) return true;
|
if(data[nick] && data[nick][0] > entry[0]) return true;
|
||||||
data[pguid] = entry;
|
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.
|
// it is all the same to renderData.
|
||||||
chat.renderData(data, 'chatcompact', oldMsgsWereAdded);
|
chat.renderData(data, 'chatcompact', oldMsgsWereAdded);
|
||||||
}
|
}
|
||||||
@ -350,7 +350,7 @@ window.chat.writeDataToHash = function(newData, storageHash, isPublicChannel, is
|
|||||||
|
|
||||||
|
|
||||||
// format: timestamp, autogenerated, HTML message
|
// 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];
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,8 @@ window.updateGameScoreFailCount = 0;
|
|||||||
|
|
||||||
window.updateGameScore = function(data) {
|
window.updateGameScore = function(data) {
|
||||||
if(!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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,10 @@
|
|||||||
// iitcLoaded: called after IITC and all plugins loaded
|
// iitcLoaded: called after IITC and all plugins loaded
|
||||||
// portalDetailLoaded: called when a request to load full portal detail
|
// portalDetailLoaded: called when a request to load full portal detail
|
||||||
// completes. guid, success, details parameters
|
// 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._hooks = {}
|
||||||
window.VALID_HOOKS = [
|
window.VALID_HOOKS = [
|
||||||
@ -60,30 +64,32 @@ window.VALID_HOOKS = [
|
|||||||
'publicChatDataAvailable', 'factionChatDataAvailable',
|
'publicChatDataAvailable', 'factionChatDataAvailable',
|
||||||
'requestFinished', 'nicknameClicked',
|
'requestFinished', 'nicknameClicked',
|
||||||
'geoSearch', 'iitcLoaded',
|
'geoSearch', 'iitcLoaded',
|
||||||
'portalDetailLoaded'];
|
'portalDetailLoaded', 'paneChanged'];
|
||||||
|
|
||||||
window.runHooks = function(event, data) {
|
window.runHooks = function(event, data) {
|
||||||
if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event);
|
if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event);
|
||||||
|
|
||||||
if(!_hooks[event]) return true;
|
if(!_hooks[event]) return true;
|
||||||
var interupted = false;
|
var interrupted = false;
|
||||||
$.each(_hooks[event], function(ind, callback) {
|
$.each(_hooks[event], function(ind, callback) {
|
||||||
try {
|
try {
|
||||||
if (callback(data) === false) {
|
if (callback(data) === false) {
|
||||||
interupted = true;
|
interrupted = true;
|
||||||
return false; //break from $.each
|
return false; //break from $.each
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.error('error running hook '+event+', error: '+err);
|
console.error('error running hook '+event+', error: '+err);
|
||||||
|
debugger;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return !interupted;
|
return !interrupted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window.addHook = function(event, callback) {
|
window.addHook = function(event, callback) {
|
||||||
if(VALID_HOOKS.indexOf(event) === -1) {
|
if(VALID_HOOKS.indexOf(event) === -1) {
|
||||||
console.error('addHook: Unknown event type: ' + event + ' - ignoring');
|
console.error('addHook: Unknown event type: ' + event + ' - ignoring');
|
||||||
|
debugger;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
// tile and a quadkey. Both the bounds and the quadkey are “somewhat”
|
// tile and a quadkey. Both the bounds and the quadkey are “somewhat”
|
||||||
// required to get complete data.
|
// required to get complete data.
|
||||||
//
|
//
|
||||||
// Convertion functions courtesy of
|
// Conversion functions courtesy of
|
||||||
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
||||||
|
|
||||||
|
|
||||||
|
@ -470,7 +470,7 @@ window.Render.prototype.addPortalToMapLayer = function(portal) {
|
|||||||
|
|
||||||
this.portalClusters[cid].push(portal.options.guid);
|
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
|
// 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
|
// 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)) {
|
if (this.portalClusters[cid].length < this.CLUSTER_PORTAL_LIMIT || portal.options.guid == selectedPortal || artifact.isInterestingPortal(portal.options.guid)) {
|
||||||
|
@ -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
|
// 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
|
// many requests at once.
|
||||||
this.MAX_REQUESTS = 6;
|
// 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
|
// 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
|
// 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;
|
this.MIN_TILES_PER_REQUEST = 4;
|
||||||
|
|
||||||
// number of times to retry a tile after a 'bad' error (i.e. not a timeout)
|
// 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
|
// refresh timers
|
||||||
this.MOVE_REFRESH = 1; //time, after a map move (pan/zoom) before starting the refresh processing
|
this.MOVE_REFRESH = 1; //time, after a map move (pan/zoom) before starting the refresh processing
|
||||||
|
@ -12,50 +12,58 @@
|
|||||||
;(function(){
|
;(function(){
|
||||||
|
|
||||||
var requestParameterMunges = [
|
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
|
// 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
|
||||||
'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO
|
// at this time. If that auto-detection breaks, it may be easier to quicky add a munge set by hand than update
|
||||||
'dashboard.getGameScore': '4oid643d9zc168hs', // GET_GAME_SCORE
|
// the regular expressions, so the list-based code remains available for the future
|
||||||
'dashboard.getPaginatedPlexts': 's1msyywq51ntudpe', // GET_PAGINATED_PLEXTS
|
// // set 11 - 2013-12-06
|
||||||
'dashboard.getThinnedEntities': '4467ff9bgxxe4csa', // GET_THINNED_ENTITIES
|
// {
|
||||||
'dashboard.getPortalDetails': 'c00thnhf1yp3z6mn', // GET_PORTAL_DETAILS
|
// 'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO
|
||||||
'dashboard.redeemReward': '66l9ivg39ygfqqjm', // REDEEM_REWARD
|
// 'dashboard.getGameScore': '4oid643d9zc168hs', // GET_GAME_SCORE
|
||||||
'dashboard.sendInviteEmail': 'cgb7hi5hglv0xx8k', // SEND_INVITE_EMAIL
|
// 'dashboard.getPaginatedPlexts': 's1msyywq51ntudpe', // GET_PAGINATED_PLEXTS
|
||||||
'dashboard.sendPlext': 'etn9xq7brd6947kq', // SEND_PLEXT
|
// 'dashboard.getThinnedEntities': '4467ff9bgxxe4csa', // GET_THINNED_ENTITIES
|
||||||
|
// 'dashboard.getPortalDetails': 'c00thnhf1yp3z6mn', // GET_PORTAL_DETAILS
|
||||||
// common parameters
|
// 'dashboard.redeemReward': 'ivshfv9zvyfxyqcd', // REDEEM_REWARD
|
||||||
method: 'yyngyttbmmbuvdpa',
|
// 'dashboard.sendInviteEmail': '1rsx15vc0m8wwdax', // SEND_INVITE_EMAIL
|
||||||
version: 'avz401t36lzrapis',
|
// 'dashboard.sendPlext': 'tods2imd0xcfsug6', // SEND_PLEXT
|
||||||
version_parameter: 'c5d0a5d608f729a1232bebdc12fb86ba5fb6c43f',
|
//
|
||||||
|
// // common parameters
|
||||||
// GET_THINNED_ENTITIES
|
// method: '0wvzluo8av4sk17f',
|
||||||
quadKeys: '1mpmxz2yun22rwnn',
|
// version: 'paeh4g353xu06kfg',
|
||||||
|
// version_parameter: '4acc1e3230c3fd66be3422c0df8dc637336bbd7c',
|
||||||
// GET_PAGINATED_PLEXTS
|
//
|
||||||
desiredNumItems: 'nzd23jqm9k1cnnij',
|
// // GET_THINNED_ENTITIES
|
||||||
minLatE6: '0dod6onpa1s4fezp',
|
// quadKeys: 'ilgv0w4dlldky1yh',
|
||||||
minLngE6: 'soass3t7mm7anneo',
|
//
|
||||||
maxLatE6: 'cvarmr3o00ngylo1',
|
// // GET_PORTAL_DETAILS
|
||||||
maxLngE6: 'udzwnlx07hzd3bfo',
|
// guid: '7o8tzmj6oxz1n5w3',
|
||||||
minTimestampMs: '9iiiks138gkf8xho',
|
//
|
||||||
maxTimestampMs: '94wm0u3sc3sgzq7x',
|
// // REDEEM_REWARD
|
||||||
chatTab: 'tqfj4a3okzn5v5o1',
|
// passcode: 'passcode', // no munging on this parameter
|
||||||
ascendingTimestampOrder: '5jv1m90sq35u6utq',
|
//
|
||||||
|
// // SEND_INVITE_EMAIL
|
||||||
// SEND_PLEXT
|
// inviteeEmailAddress: 'p4rwszdfovuwfdgp',
|
||||||
message: '8exta9k7y8huhqmc',
|
//
|
||||||
latE6: 'kqek161gza3kjcry',
|
// // GET_PAGINATED_PLEXTS
|
||||||
lngE6: '3dlxsqrjj2vcmhbc',
|
// desiredNumItems: 'kxsbuvc90l6f40xn',
|
||||||
// chatTab: 'efaznrayv5n3jxs0', //guessed parameter name - only seen munged
|
// minLatE6: 'llizye3i5dbapxac',
|
||||||
|
// minLngE6: 'w01zpiba1mn5tsab',
|
||||||
// GET_PORTAL_DETAILS
|
// maxLatE6: 'd5phhqzj2tbsq599',
|
||||||
guid: 'seg6ohxgnqf9xu9w',
|
// maxLngE6: 'avq5srnvg431aehn',
|
||||||
|
// minTimestampMs: 'mhsav5by25wi4s46',
|
||||||
// SEND_INVITE_EMAIL
|
// maxTimestampMs: 'hpu7l8h7eccwytyt',
|
||||||
inviteeEmailAddress: '8exta9k7y8huhqmc',
|
// chatTab: 'q9343nem7hs1v37b',
|
||||||
},
|
// ascendingTimestampOrder: '7pc5c9ggh03pig1b',
|
||||||
|
//
|
||||||
|
// // SEND_PLEXT
|
||||||
|
// message: '8exta9k7y8huhqmc',
|
||||||
|
// latE6: '7ffwyf3zd2yf8xam',
|
||||||
|
// lngE6: 'n7ewiach2v22iy20',
|
||||||
|
//// chatTab: 'q9343nem7hs1v37b', // duplicate from GET_PAGINATED_PLEXTS
|
||||||
|
//
|
||||||
|
// },
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
window.show = function(id) {
|
window.show = function(id) {
|
||||||
window.hideall();
|
window.hideall();
|
||||||
|
|
||||||
|
runHooks("paneChanged", id);
|
||||||
|
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case 'full':
|
case 'full':
|
||||||
window.chat.show('full');
|
window.chat.show('full');
|
||||||
@ -27,9 +29,6 @@ window.show = function(id) {
|
|||||||
case 'info':
|
case 'info':
|
||||||
window.smartphone.sideButton.click();
|
window.smartphone.sideButton.click();
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
window.smartphone.mapButton.click();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof android !== 'undefined' && android && android.switchToPane) {
|
if (typeof android !== 'undefined' && android && android.switchToPane) {
|
||||||
|
@ -21,6 +21,11 @@ window.getPortalLinks = function(guid) {
|
|||||||
return links;
|
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
|
// search through the fields for all that reference a portal
|
||||||
window.getPortalFields = function(guid) {
|
window.getPortalFields = function(guid) {
|
||||||
@ -40,6 +45,11 @@ window.getPortalFields = function(guid) {
|
|||||||
return fields;
|
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
|
// 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)
|
// (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
|
// no luck finding portal lat/lng
|
||||||
return undefined;
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/// PORTAL DETAIL //////////////////////////////////////
|
/// 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
|
// 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
|
// 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
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
window.renderPortalDetails = function(guid) {
|
window.renderPortalDetails = function(guid) {
|
||||||
selectPortal(window.portals[guid] ? guid : null);
|
selectPortal(window.portals[guid] ? guid : null);
|
||||||
|
|
||||||
if (!portalDetail.isFresh(guid)) {
|
if (guid && !portalDetail.isFresh(guid)) {
|
||||||
portalDetail.request(guid);
|
portalDetail.request(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +26,11 @@ window.renderPortalDetails = function(guid) {
|
|||||||
var data = portal.options.data;
|
var data = portal.options.data;
|
||||||
var details = portalDetail.get(guid);
|
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 modDetails = details ? '<div class="mods">'+getModDetails(details)+'</div>' : '';
|
||||||
var miscDetails = details ? getPortalMiscDetails(guid,details) : '';
|
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
|
// portal level. start with basic data - then extend with fractional info in tooltip if available
|
||||||
var levelInt = data ? data.level : getPortalLevel(details);
|
var levelInt = portal.options.level;
|
||||||
var levelDetails = data.level;
|
var levelDetails = portal.options.level;
|
||||||
if (details) {
|
if (details) {
|
||||||
levelDetails = getPortalLevel(details);
|
levelDetails = getPortalLevel(details);
|
||||||
if(levelDetails != 8) {
|
if(levelDetails != 8) {
|
||||||
@ -109,7 +114,7 @@ window.renderPortalDetails = function(guid) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// non-android - a permalink for the portal
|
// 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>' );
|
linkDetails.push ( '<aside>'+permaHtml+'</aside>' );
|
||||||
|
|
||||||
// and a map link popup dialog
|
// and a map link popup dialog
|
||||||
@ -178,7 +183,9 @@ window.getPortalMiscDetails = function(guid,d) {
|
|||||||
: null;
|
: null;
|
||||||
var sinceText = time ? ['since', time] : 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
|
// collect and html-ify random data
|
||||||
var randDetailsData = [];
|
var randDetailsData = [];
|
||||||
@ -189,7 +196,7 @@ window.getPortalMiscDetails = function(guid,d) {
|
|||||||
randDetailsData.push (
|
randDetailsData.push (
|
||||||
getRangeText(d), getEnergyText(d),
|
getRangeText(d), getEnergyText(d),
|
||||||
linksText, getAvgResoDistText(d),
|
linksText, getAvgResoDistText(d),
|
||||||
linkedFields, getAttackApGainText(d),
|
linkedFields, getAttackApGainText(d,fieldCount),
|
||||||
getHackDetailsText(d), getMitigationText(d)
|
getHackDetailsText(d), getMitigationText(d)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -193,8 +193,13 @@ window.getResonatorDetails = function(d) {
|
|||||||
// slot: which slot this resonator occupies. Starts with 0 (east) and
|
// slot: which slot this resonator occupies. Starts with 0 (east) and
|
||||||
// rotates clockwise. So, last one is 7 (southeast).
|
// rotates clockwise. So, last one is 7 (southeast).
|
||||||
window.renderResonatorDetails = function(slot, level, nrg, dist, nick) {
|
window.renderResonatorDetails = function(slot, level, nrg, dist, nick) {
|
||||||
|
if(OCTANTS[slot] === 'N')
|
||||||
|
var className = 'meter north';
|
||||||
|
else
|
||||||
|
var className = 'meter';
|
||||||
|
|
||||||
if(level === 0) {
|
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 {
|
} else {
|
||||||
var max = RESO_NRG[level];
|
var max = RESO_NRG[level];
|
||||||
var fillGrade = nrg/max*100;
|
var fillGrade = nrg/max*100;
|
||||||
@ -209,19 +214,19 @@ window.renderResonatorDetails = function(slot, level, nrg, dist, nick) {
|
|||||||
|
|
||||||
var color = (level < 3 ? "#9900FF" : "#FFFFFF");
|
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 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;
|
nick = nick ? '<span class="nickname">'+nick+'</span>' : null;
|
||||||
return [meter, nick || ''];
|
return [meter, nick || ''];
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate AP gain from destroying portal and then capturing it by deploying resonators
|
// calculate AP gain from destroying portal and then capturing it by deploying resonators
|
||||||
window.getAttackApGainText = function(d) {
|
window.getAttackApGainText = function(d,fieldCount) {
|
||||||
var breakdown = getAttackApGain(d);
|
var breakdown = getAttackApGain(d,fieldCount);
|
||||||
var totalGain = breakdown.enemyAp;
|
var totalGain = breakdown.enemyAp;
|
||||||
|
|
||||||
function tt(text) {
|
function tt(text) {
|
||||||
|
@ -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
|
// (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)
|
// the stats work and combine - jon 2013-06-26)
|
||||||
|
|
||||||
// link amps scale: first is full, second half, the last two a quarter
|
// link amps scale: first is full, second a quarter, the last two an eigth
|
||||||
var scale = [1.0, 0.5, 0.25, 0.25];
|
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;
|
var count = 0;
|
||||||
|
|
||||||
$.each(d.portalV2.linkedModArray, function(ind, mod) {
|
var linkAmps = getPortalModsByType(d, 'LINK_AMPLIFIER');
|
||||||
if(mod && mod.type === 'LINK_AMPLIFIER' && mod.stats && mod.stats.LINK_RANGE_MULTIPLIER) {
|
|
||||||
|
$.each(linkAmps, function(ind, mod) {
|
||||||
// link amp stat LINK_RANGE_MULTIPLIER is 2000 for rare, and gives 2x boost to the range
|
// 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;
|
var baseMultiplier = mod.stats.LINK_RANGE_MULTIPLIER/1000;
|
||||||
boost += (baseMultiplier-1)*scale[count];
|
boost += baseMultiplier*scale[count];
|
||||||
count++;
|
count++;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return boost;
|
return (count > 0) ? boost : 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -99,7 +100,9 @@ window.getAvgResoDist = function(d) {
|
|||||||
return resos ? sum/resos : 0;
|
return resos ? sum/resos : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.getAttackApGain = function(d) {
|
window.getAttackApGain = function(d,fieldCount) {
|
||||||
|
if (!fieldCount) fieldCount = 0;
|
||||||
|
|
||||||
var resoCount = 0;
|
var resoCount = 0;
|
||||||
var maxResonators = MAX_RESO_PER_PLAYER.slice(0);
|
var maxResonators = MAX_RESO_PER_PLAYER.slice(0);
|
||||||
var curResonators = [ 0, 0, 0, 0, 0, 0, 0, 0, 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 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 resoAp = resoCount * DESTROY_RESONATOR;
|
||||||
var linkAp = linkCount * DESTROY_LINK;
|
var linkAp = linkCount * DESTROY_LINK;
|
||||||
@ -307,4 +310,30 @@ window.getPortalHackDetails = function(d) {
|
|||||||
return {cooldown: cooldownTime, hacks: numHacks, burnout: cooldownTime*(numHacks-1)};
|
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'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -66,24 +66,36 @@ window.runOnSmartphonesBeforeBoot = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.smartphoneInfo = function(data) {
|
window.smartphoneInfo = function(data) {
|
||||||
var d = data.portalDetails;
|
var guid = data.selectedPortalGuid;
|
||||||
var lvl = Math.floor(getPortalLevel(d));
|
if(!window.portals[guid]) return;
|
||||||
if(lvl == 0)
|
|
||||||
var t = '<span class="portallevel">L' + lvl + '</span>';
|
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
|
else
|
||||||
var t = '<span class="portallevel" style="background: '+COLORS_LVL[lvl]+';">L' + lvl + '</span>';
|
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;
|
var l,v,max,perc;
|
||||||
for(var i=0;i<8;i++)
|
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) {
|
if(reso) {
|
||||||
l = parseInt(reso.level);
|
l = parseInt(reso.level);
|
||||||
v = parseInt(reso.energyTotal);
|
v = parseInt(reso.energyTotal);
|
||||||
@ -97,10 +109,11 @@ window.smartphoneInfo = function(data) {
|
|||||||
perc = 0;
|
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 class="filllevel" style="width:'+perc+'%;"></div>';
|
||||||
t += '</div>'
|
t += '</div>'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$('#mobileinfo').html(t);
|
$('#mobileinfo').html(t);
|
||||||
}
|
}
|
||||||
@ -113,7 +126,7 @@ window.runOnSmartphonesAfterBoot = function() {
|
|||||||
|
|
||||||
// add a div/hook for updating mobile info
|
// add a div/hook for updating mobile info
|
||||||
$('#updatestatus').prepend('<div id="mobileinfo" onclick="show(\'info\')"></div>');
|
$('#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
|
// 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>');
|
$('#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_LINKS = 200;
|
||||||
window.MAX_DRAWN_FIELDS = 100;
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,9 @@ window.convertCookieToLocalStorage = function(name) {
|
|||||||
// add thousand separators to given number.
|
// add thousand separators to given number.
|
||||||
// http://stackoverflow.com/a/1990590/1684530 by Doug Neiner.
|
// http://stackoverflow.com/a/1990590/1684530 by Doug Neiner.
|
||||||
window.digits = function(d) {
|
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 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -267,11 +269,11 @@ window.androidCopy = function(text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.androidPermalink = function() {
|
window.androidPermalink = function() {
|
||||||
if(typeof android === 'undefined' || !android || !android.copy)
|
if(typeof android === 'undefined' || !android || !android.intentPosLink)
|
||||||
return true; // i.e. execute other actions
|
return true; // i.e. execute other actions
|
||||||
|
|
||||||
var center = map.getCenter();
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
74
external/L.Geodesic.js
vendored
@ -35,47 +35,53 @@ Modified by qnstie 2013-07-17 to maintain compatibility with Leaflet.draw
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function geodesicConvertLine(startLatlng, endLatlng, convertedPoints) {
|
// alternative geodesic line intermediate points function
|
||||||
var i,
|
// as north/south lines have very little curvature in the projection, we cam use longitude (east/west) seperation
|
||||||
R = 6378137, // earth radius in meters (doesn't have to be exact)
|
// to calculate intermediate points. hopeefully this will avoid the rounding issues seen in the full intermediate
|
||||||
maxlength = 5000, // meters before splitting
|
// points code that have been seen
|
||||||
d2r = L.LatLng.DEG_TO_RAD,
|
function geodesicConvertLine(startLatLng, endLatLng, convertedPoints) {
|
||||||
r2d = L.LatLng.RAD_TO_DEG,
|
var R = 6378137; // earth radius in meters (doesn't have to be exact)
|
||||||
lat1, lat2, lng1, lng2, dLng, d, segments,
|
var d2r = L.LatLng.DEG_TO_RAD;
|
||||||
f, A, B, x, y, z, fLat, fLng;
|
var r2d = L.LatLng.RAD_TO_DEG;
|
||||||
|
|
||||||
dLng = (endLatlng.lng - startLatlng.lng) * d2r;
|
// maths based on http://williams.best.vwh.net/avform.htm#Int
|
||||||
lat1 = startLatlng.lat * d2r;
|
|
||||||
lat2 = endLatlng.lat * d2r;
|
|
||||||
lng1 = startLatlng.lng * d2r;
|
|
||||||
lng2 = endLatlng.lng * d2r;
|
|
||||||
|
|
||||||
// http://en.wikipedia.org/wiki/Great-circle_distance
|
var lat1 = startLatLng.lat * d2r;
|
||||||
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 lat2 = endLatLng.lat * d2r;
|
||||||
|
var lng1 = startLatLng.lng * d2r;
|
||||||
|
var lng2 = endLatLng.lng * d2r;
|
||||||
|
|
||||||
segments = Math.ceil(d * R / maxlength);
|
var dLng = lng2-lng1;
|
||||||
// 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);
|
|
||||||
|
|
||||||
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) {
|
L.geodesicConvertLines = function (latlngs, fill) {
|
||||||
if (latlngs.length == 0) {
|
if (latlngs.length == 0) {
|
||||||
return [];
|
return [];
|
||||||
|
53
external/leaflet-src.js
vendored
@ -7,7 +7,7 @@
|
|||||||
var oldL = window.L,
|
var oldL = window.L,
|
||||||
L = {};
|
L = {};
|
||||||
|
|
||||||
L.version = '0.7';
|
L.version = '0.7.1';
|
||||||
|
|
||||||
// define Leaflet for Node module pattern loaders, including Browserify
|
// define Leaflet for Node module pattern loaders, including Browserify
|
||||||
if (typeof module === 'object' && typeof module.exports === 'object') {
|
if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||||
@ -134,21 +134,16 @@ L.Util = {
|
|||||||
}
|
}
|
||||||
return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');
|
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) {
|
template: function (str, data) {
|
||||||
var cache = L.Util._templateCache = L.Util._templateCache || {};
|
return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
|
||||||
cache[str] = cache[str] || L.Util.compileTemplate(str, data);
|
var value = data[key];
|
||||||
return cache[str](data);
|
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) {
|
isArray: Array.isArray || function (obj) {
|
||||||
@ -534,7 +529,7 @@ L.Mixin.Events.fire = L.Mixin.Events.fireEvent;
|
|||||||
|
|
||||||
doc = document.documentElement,
|
doc = document.documentElement,
|
||||||
ie3d = ie && ('transition' in doc.style),
|
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,
|
gecko3d = 'MozPerspective' in doc.style,
|
||||||
opera3d = 'OTransition' in doc.style,
|
opera3d = 'OTransition' in doc.style,
|
||||||
any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d || opera3d) && !phantomjs;
|
any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d || opera3d) && !phantomjs;
|
||||||
@ -1070,11 +1065,6 @@ L.DomUtil = {
|
|||||||
|
|
||||||
if (!disable3D && L.Browser.any3d) {
|
if (!disable3D && L.Browser.any3d) {
|
||||||
el.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(point);
|
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 {
|
} else {
|
||||||
el.style.left = point.x + 'px';
|
el.style.left = point.x + 'px';
|
||||||
el.style.top = point.y + 'px';
|
el.style.top = point.y + 'px';
|
||||||
@ -1770,6 +1760,8 @@ L.Map = L.Class.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
invalidateSize: function (options) {
|
invalidateSize: function (options) {
|
||||||
|
if (!this._loaded) { return this; }
|
||||||
|
|
||||||
options = L.extend({
|
options = L.extend({
|
||||||
animate: false,
|
animate: false,
|
||||||
pan: true
|
pan: true
|
||||||
@ -1779,8 +1771,6 @@ L.Map = L.Class.extend({
|
|||||||
this._sizeChanged = true;
|
this._sizeChanged = true;
|
||||||
this._initialCenter = null;
|
this._initialCenter = null;
|
||||||
|
|
||||||
if (!this._loaded) { return this; }
|
|
||||||
|
|
||||||
var newSize = this.getSize(),
|
var newSize = this.getSize(),
|
||||||
oldCenter = oldSize.divideBy(2).round(),
|
oldCenter = oldSize.divideBy(2).round(),
|
||||||
newCenter = newSize.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)
|
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 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
|
(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;
|
this._tiles[tilePoint.x + ':' + tilePoint.y] = tile;
|
||||||
|
|
||||||
@ -4481,10 +4469,10 @@ L.FeatureGroup = L.LayerGroup.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_propagateEvent: function (e) {
|
_propagateEvent: function (e) {
|
||||||
e = L.extend({}, e, {
|
e = L.extend({
|
||||||
layer: e.target,
|
layer: e.target,
|
||||||
target: this
|
target: this
|
||||||
});
|
}, e);
|
||||||
this.fire(e.type, 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.)
|
* 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 = {
|
L.LineUtil = {
|
||||||
|
|
||||||
@ -5988,6 +5976,7 @@ L.CircleMarker = L.Circle.extend({
|
|||||||
if (this._popup && this._popup._isOpen) {
|
if (this._popup && this._popup._isOpen) {
|
||||||
this._popup.setLatLng(latlng);
|
this._popup.setLatLng(latlng);
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
setRadius: function (radius) {
|
setRadius: function (radius) {
|
||||||
@ -6769,7 +6758,7 @@ L.Draggable = L.Class.extend({
|
|||||||
L.DomUtil.enableImageDrag();
|
L.DomUtil.enableImageDrag();
|
||||||
L.DomUtil.enableTextSelection();
|
L.DomUtil.enableTextSelection();
|
||||||
|
|
||||||
if (this._moved) {
|
if (this._moved && this._moving) {
|
||||||
// ensure drag is not fired after dragend
|
// ensure drag is not fired after dragend
|
||||||
L.Util.cancelAnimFrame(this._animRequest);
|
L.Util.cancelAnimFrame(this._animRequest);
|
||||||
|
|
||||||
@ -8903,8 +8892,8 @@ if (L.DomUtil.TRANSITION) {
|
|||||||
|
|
||||||
L.Map.include(!L.DomUtil.TRANSITION ? {} : {
|
L.Map.include(!L.DomUtil.TRANSITION ? {} : {
|
||||||
|
|
||||||
_catchTransitionEnd: function () {
|
_catchTransitionEnd: function (e) {
|
||||||
if (this._animatingZoom) {
|
if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) {
|
||||||
this._onZoomTransitionEnd();
|
this._onZoomTransitionEnd();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
8
external/leaflet.js
vendored
9
main.js
@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @id ingress-intel-total-conversion@jonatkins
|
// @id ingress-intel-total-conversion@jonatkins
|
||||||
// @name IITC: Ingress intel map total conversion
|
// @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
|
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||||
// @updateURL @@UPDATEURL@@
|
// @updateURL @@UPDATEURL@@
|
||||||
// @downloadURL @@DOWNLOADURL@@
|
// @downloadURL @@DOWNLOADURL@@
|
||||||
@ -39,8 +39,11 @@ if(!d) {
|
|||||||
// page doesn’t have a script tag with player information.
|
// page doesn’t have a script tag with player information.
|
||||||
if(document.getElementById('header_email')) {
|
if(document.getElementById('header_email')) {
|
||||||
// however, we are logged in.
|
// however, we are logged in.
|
||||||
setTimeout('location.reload();', 3*1000);
|
// it used to be regularly common to get temporary 'account not enabled' messages from the intel site.
|
||||||
throw("Page doesn't have player data, but you are logged in. Reloading in 3s.");
|
// 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
|
// FIXME: handle nia takedown in progress
|
||||||
throw("Couldn't retrieve player data. Are you logged in?");
|
throw("Couldn't retrieve player data. Are you logged in?");
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.cradle.iitc_mobile"
|
package="com.cradle.iitc_mobile"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto"
|
||||||
android:versionCode="61"
|
android:versionCode="62"
|
||||||
android:versionName="0.10.0">
|
android:versionName="0.10.1">
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="14"
|
android:minSdkVersion="14"
|
||||||
@ -99,7 +99,7 @@
|
|||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:icon="@drawable/copy"
|
android:icon="@drawable/ic_action_copy"
|
||||||
android:label="@string/activity_share_to_clipboard"
|
android:label="@string/activity_share_to_clipboard"
|
||||||
android:noHistory="false">
|
android:noHistory="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 171 B |
BIN
mobile/res/drawable-hdpi/ic_action_about.png
Normal file
After Width: | Height: | Size: 646 B |
BIN
mobile/res/drawable-hdpi/ic_action_add_to_queue.png
Normal file
After Width: | Height: | Size: 356 B |
BIN
mobile/res/drawable-hdpi/ic_action_cc_bcc.png
Normal file
After Width: | Height: | Size: 707 B |
BIN
mobile/res/drawable-hdpi/ic_action_copy.png
Normal file
After Width: | Height: | Size: 375 B |
BIN
mobile/res/drawable-hdpi/ic_action_data_usage.png
Normal file
After Width: | Height: | Size: 633 B |
BIN
mobile/res/drawable-hdpi/ic_action_error.png
Normal file
After Width: | Height: | Size: 345 B |
BIN
mobile/res/drawable-hdpi/ic_action_full_screen.png
Normal file
After Width: | Height: | Size: 587 B |
BIN
mobile/res/drawable-hdpi/ic_action_group.png
Normal file
After Width: | Height: | Size: 769 B |
BIN
mobile/res/drawable-hdpi/ic_action_location_found.png
Normal file
After Width: | Height: | Size: 638 B |
BIN
mobile/res/drawable-hdpi/ic_action_map.png
Normal file
After Width: | Height: | Size: 799 B |
BIN
mobile/res/drawable-hdpi/ic_action_new_event.png
Normal file
After Width: | Height: | Size: 407 B |
BIN
mobile/res/drawable-hdpi/ic_action_paste.png
Normal file
After Width: | Height: | Size: 462 B |
BIN
mobile/res/drawable-hdpi/ic_action_place.png
Normal file
After Width: | Height: | Size: 555 B |
BIN
mobile/res/drawable-hdpi/ic_action_refresh.png
Normal file
After Width: | Height: | Size: 677 B |
BIN
mobile/res/drawable-hdpi/ic_action_search.png
Normal file
After Width: | Height: | Size: 639 B |
BIN
mobile/res/drawable-hdpi/ic_action_share.png
Normal file
After Width: | Height: | Size: 561 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
mobile/res/drawable-hdpi/ic_action_view_as_list.png
Normal file
After Width: | Height: | Size: 307 B |
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 435 B |
BIN
mobile/res/drawable-hdpi/ic_action_warning.png
Normal file
After Width: | Height: | Size: 515 B |
BIN
mobile/res/drawable-hdpi/ic_action_web_site.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 158 B |
BIN
mobile/res/drawable-mdpi/ic_action_about.png
Normal file
After Width: | Height: | Size: 434 B |
BIN
mobile/res/drawable-mdpi/ic_action_add_to_queue.png
Normal file
After Width: | Height: | Size: 303 B |
BIN
mobile/res/drawable-mdpi/ic_action_cc_bcc.png
Normal file
After Width: | Height: | Size: 497 B |
BIN
mobile/res/drawable-mdpi/ic_action_copy.png
Normal file
After Width: | Height: | Size: 288 B |
BIN
mobile/res/drawable-mdpi/ic_action_data_usage.png
Normal file
After Width: | Height: | Size: 464 B |
BIN
mobile/res/drawable-mdpi/ic_action_error.png
Normal file
After Width: | Height: | Size: 299 B |
BIN
mobile/res/drawable-mdpi/ic_action_full_screen.png
Normal file
After Width: | Height: | Size: 461 B |
BIN
mobile/res/drawable-mdpi/ic_action_group.png
Normal file
After Width: | Height: | Size: 543 B |
BIN
mobile/res/drawable-mdpi/ic_action_location_found.png
Normal file
After Width: | Height: | Size: 460 B |
BIN
mobile/res/drawable-mdpi/ic_action_map.png
Normal file
After Width: | Height: | Size: 603 B |
BIN
mobile/res/drawable-mdpi/ic_action_new_event.png
Normal file
After Width: | Height: | Size: 369 B |
BIN
mobile/res/drawable-mdpi/ic_action_paste.png
Normal file
After Width: | Height: | Size: 331 B |
BIN
mobile/res/drawable-mdpi/ic_action_place.png
Normal file
After Width: | Height: | Size: 393 B |
BIN
mobile/res/drawable-mdpi/ic_action_refresh.png
Normal file
After Width: | Height: | Size: 492 B |
BIN
mobile/res/drawable-mdpi/ic_action_search.png
Normal file
After Width: | Height: | Size: 449 B |
BIN
mobile/res/drawable-mdpi/ic_action_share.png
Normal file
After Width: | Height: | Size: 418 B |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
BIN
mobile/res/drawable-mdpi/ic_action_view_as_list.png
Normal file
After Width: | Height: | Size: 246 B |
Before Width: | Height: | Size: 334 B After Width: | Height: | Size: 334 B |
BIN
mobile/res/drawable-mdpi/ic_action_warning.png
Normal file
After Width: | Height: | Size: 410 B |
BIN
mobile/res/drawable-mdpi/ic_action_web_site.png
Normal file
After Width: | Height: | Size: 733 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.3 KiB |