Merge branch 'highlighter' of https://github.com/vita10gy/ingress-intel-total-conversion into highlighter
This commit is contained in:
commit
9908175bb2
50
build.py
50
build.py
@ -8,7 +8,14 @@ import base64
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import json
|
||||
import shelve
|
||||
import hashlib
|
||||
|
||||
try:
|
||||
import urllib2
|
||||
except ImportError:
|
||||
import urllib.request as urllib2
|
||||
|
||||
# load settings file
|
||||
from buildsettings import buildSettings
|
||||
@ -66,6 +73,33 @@ def loaderRaw(var):
|
||||
fn = var.group(1)
|
||||
return readfile(fn)
|
||||
|
||||
def loaderMD(var):
|
||||
fn = var.group(1)
|
||||
# use different MD.dat's for python 2 vs 3 incase user switches versions, as they are not compatible
|
||||
db = shelve.open('build/MDv' + str(sys.version_info.major) + '.dat')
|
||||
if 'files' in db:
|
||||
files = db['files']
|
||||
else:
|
||||
files = {}
|
||||
file = readfile(fn)
|
||||
filemd5 = hashlib.md5(file.encode('utf8')).hexdigest()
|
||||
# check if file has already been parsed by the github api
|
||||
if fn in files and filemd5 in files[fn]:
|
||||
# use the stored copy if nothing has changed to avoid hiting the api more then the 60/hour when not signed in
|
||||
db.close()
|
||||
return files[fn][filemd5]
|
||||
else:
|
||||
url = 'https://api.github.com/markdown'
|
||||
payload = {'text': file, 'mode': 'markdown'}
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
req = urllib2.Request(url, json.dumps(payload).encode('utf8'), headers)
|
||||
md = urllib2.urlopen(req).read().decode('utf8').replace('\n', '').replace('\'', '\\\'')
|
||||
files[fn] = {}
|
||||
files[fn][filemd5] = md
|
||||
db['files'] = files
|
||||
db.close()
|
||||
return md
|
||||
|
||||
def loaderImage(var):
|
||||
fn = var.group(1)
|
||||
return 'data:image/png;base64,{0}'.format(base64.encodestring(open(fn, 'rb').read()).decode('utf8').replace('\n', ''))
|
||||
@ -86,6 +120,7 @@ def doReplacements(script,updateUrl,downloadUrl):
|
||||
|
||||
script = re.sub('@@INCLUDERAW:([0-9a-zA-Z_./-]+)@@', loaderRaw, script)
|
||||
script = re.sub('@@INCLUDESTRING:([0-9a-zA-Z_./-]+)@@', loaderString, script)
|
||||
script = re.sub('@@INCLUDEMD:([0-9a-zA-Z_./-]+)@@', loaderMD, script)
|
||||
script = re.sub('@@INCLUDEIMAGE:([0-9a-zA-Z_./-]+)@@', loaderImage, script)
|
||||
|
||||
script = script.replace('@@BUILDDATE@@', buildDate)
|
||||
@ -156,6 +191,14 @@ for fn in glob.glob("plugins/*.user.js"):
|
||||
metafn = fn.replace('.user.js', '.meta.js')
|
||||
saveScriptAndMeta(script, os.path.join(outDir,fn), os.path.join(outDir,metafn))
|
||||
|
||||
def copytree(src, dst, symlinks=False, ignore=None):
|
||||
for item in os.listdir(src):
|
||||
s = os.path.join(src, item)
|
||||
d = os.path.join(dst, item)
|
||||
if os.path.isdir(s):
|
||||
shutil.copytree(s, d, symlinks, ignore)
|
||||
else:
|
||||
shutil.copy2(s, d)
|
||||
|
||||
# if we're building mobile too
|
||||
if buildMobile:
|
||||
@ -169,7 +212,12 @@ if buildMobile:
|
||||
pass
|
||||
shutil.copy(os.path.join(outDir,"total-conversion-build.user.js"), "mobile/assets/iitc.js")
|
||||
|
||||
# TODO? also copy plugins - once the mobile app supports plugins, that is
|
||||
# also copy plugins
|
||||
try:
|
||||
os.makedirs("mobile/assets/plugins")
|
||||
except:
|
||||
pass
|
||||
copytree(os.path.join(outDir,"plugins"), "mobile/assets/plugins")
|
||||
|
||||
|
||||
# now launch 'ant' to build the mobile project
|
||||
|
@ -118,8 +118,9 @@ window.setupMap = function() {
|
||||
//MapQuest offer tiles - http://developer.mapquest.com/web/products/open/map
|
||||
//their usage policy has no limits (except required notification above 4000 tiles/sec - we're perhaps at 50 tiles/sec based on CloudMade stats)
|
||||
var mqSubdomains = [ 'otile1','otile2', 'otile3', 'otile4' ];
|
||||
var mqTileUrlPrefix = window.location.protocol !== 'https:' ? 'http://{s}.mqcdn.com' : 'https://{s}-s.mqcdn.com';
|
||||
var mqMapOpt = {attribution: osmAttribution+', Tiles Courtesy of MapQuest', mazZoom: 18, detectRetena: true, subdomains: mqSubdomains};
|
||||
var mqMap = new L.TileLayer('http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg',mqMapOpt);
|
||||
var mqMap = new L.TileLayer(mqTileUrlPrefix+'/tiles/1.0.0/map/{z}/{x}/{y}.jpg',mqMapOpt);
|
||||
//MapQuest satellite coverage outside of the US is rather limited - so not really worth having as we have google as an option
|
||||
//var mqSatOpt = {attribution: 'Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency', mazZoom: 18, detectRetena: true, subdomains: mqSubdomains};
|
||||
//var mqSat = new L.TileLayer('http://{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg',mqSatOpt);
|
||||
@ -128,8 +129,8 @@ window.setupMap = function() {
|
||||
/*0*/ mqMap,
|
||||
/*1*/ new L.Google('INGRESS'),
|
||||
/*2*/ new L.Google('ROADMAP'),
|
||||
/*3*/ new L.Google('SATELLITE'),
|
||||
/*4*/ new L.Google('HYBRID')
|
||||
/*3*/ new L.Google('SATELLITE',{maxZoom:20}),
|
||||
/*4*/ new L.Google('HYBRID',{maxZoom:20})
|
||||
];
|
||||
|
||||
|
||||
|
10
code/chat.js
10
code/chat.js
@ -410,12 +410,12 @@ window.chat.renderMsg = function(msg, nick, time, team, msgToPlayer, systemNarro
|
||||
var s = 'style="cursor:pointer; color:'+color+'"';
|
||||
var title = nick.length >= 8 ? 'title="'+nick+'" class="help"' : '';
|
||||
var i = ['<span class="invisep"><</span>', '<span class="invisep">></span>'];
|
||||
return '<tr><td>'+t+'</td><td>'+i[0]+'<mark class="nickname" onclick="window.chat.nicknameClicked(event, \'' + nick + '\')" ' + s + '>'+ nick+'</mark>'+i[1]+'</td><td>'+msg+'</td></tr>';
|
||||
return '<tr><td>'+t+'</td><td>'+i[0]+'<mark class="nickname" ' + s + '>'+ nick+'</mark>'+i[1]+'</td><td>'+msg+'</td></tr>';
|
||||
}
|
||||
|
||||
window.chat.addNickname= function(nick){
|
||||
var c = document.getElementById("chattext");
|
||||
c.value = [c.value, nick, " "].join(" ").trim() + " ";
|
||||
c.value = [c.value.trim(), nick].join(" ").trim() + " ";
|
||||
c.focus()
|
||||
}
|
||||
|
||||
@ -589,7 +589,11 @@ window.chat.setup = function() {
|
||||
window.requests.addRefreshFunction(chat.request);
|
||||
|
||||
var cls = PLAYER.team === 'ALIENS' ? 'enl' : 'res';
|
||||
$('#chatinput mark').addClass(cls)
|
||||
$('#chatinput mark').addClass(cls);
|
||||
|
||||
$(window).on('click', '.nickname', function(event) {
|
||||
window.chat.nicknameClicked(event, $(this).text());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,34 +12,30 @@ window.requestData = function() {
|
||||
requests.abort();
|
||||
cleanUp();
|
||||
|
||||
var magic = convertCenterLat(map.getCenter().lat);
|
||||
var R = calculateR(magic);
|
||||
|
||||
var bounds = map.getBounds();
|
||||
// convert to point values
|
||||
topRight = convertLatLngToPoint(bounds.getNorthEast(), magic, R);
|
||||
bottomLeft = convertLatLngToPoint(bounds.getSouthWest() , magic, R);
|
||||
// how many quadrants intersect the current view?
|
||||
quadsX = Math.abs(bottomLeft.x - topRight.x);
|
||||
quadsY = Math.abs(bottomLeft.y - topRight.y);
|
||||
|
||||
var x1 = lngToTile(bounds.getNorthWest().lng, map.getZoom());
|
||||
var x2 = lngToTile(bounds.getNorthEast().lng, map.getZoom());
|
||||
var y1 = latToTile(bounds.getNorthWest().lat, map.getZoom());
|
||||
var y2 = latToTile(bounds.getSouthWest().lat, map.getZoom());
|
||||
|
||||
// will group requests by second-last quad-key quadrant
|
||||
tiles = {};
|
||||
|
||||
// walk in x-direction, starts right goes left
|
||||
for(var i = 0; i <= quadsX; i++) {
|
||||
var x = Math.abs(topRight.x - i);
|
||||
var qk = pointToQuadKey(x, topRight.y);
|
||||
var bnds = convertPointToLatLng(x, topRight.y, magic, R);
|
||||
if(!tiles[qk.slice(0, -1)]) tiles[qk.slice(0, -1)] = [];
|
||||
tiles[qk.slice(0, -1)].push(generateBoundsParams(qk, bnds));
|
||||
|
||||
// walk in y-direction, starts top, goes down
|
||||
for(var j = 1; j <= quadsY; j++) {
|
||||
var qk = pointToQuadKey(x, topRight.y + j);
|
||||
var bnds = convertPointToLatLng(x, topRight.y + j, magic, R);
|
||||
if(!tiles[qk.slice(0, -1)]) tiles[qk.slice(0, -1)] = [];
|
||||
tiles[qk.slice(0, -1)].push(generateBoundsParams(qk, bnds));
|
||||
for (var x = x1; x <= x2; x++) {
|
||||
for (var y = y1; y <= y2; y++) {
|
||||
var tile_id = pointToTileId(map.getZoom(), x, y);
|
||||
var bucket = Math.floor(x / 2) + "" + Math.floor(y / 2);
|
||||
if (!tiles[bucket])
|
||||
tiles[bucket] = [];
|
||||
tiles[bucket].push(generateBoundsParams(
|
||||
tile_id,
|
||||
tileToLat(y + 1, map.getZoom()),
|
||||
tileToLng(x, map.getZoom()),
|
||||
tileToLat(y, map.getZoom()),
|
||||
tileToLng(x + 1, map.getZoom())
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +43,7 @@ window.requestData = function() {
|
||||
portalRenderLimit.init();
|
||||
// finally send ajax requests
|
||||
$.each(tiles, function(ind, tls) {
|
||||
data = { minLevelOfDetail: -1 };
|
||||
data = { zoom: map.getZoom() };
|
||||
data.boundsParamsList = tls;
|
||||
window.requests.add(window.postAjax('getThinnedEntitiesV2', data, window.handleDataResponse, window.handleFailedRequest));
|
||||
});
|
||||
@ -78,7 +74,7 @@ window.handleDataResponse = function(data, textStatus, jqXHR) {
|
||||
// portals can be brought to front, this costs extra time. They need
|
||||
// to be in the foreground, or they cannot be clicked. See
|
||||
// https://github.com/Leaflet/Leaflet/issues/185
|
||||
var ppp = [];
|
||||
var ppp = {};
|
||||
var p2f = {};
|
||||
$.each(m, function(qk, val) {
|
||||
$.each(val.deletedGameEntityGuids || [], function(ind, guid) {
|
||||
@ -105,9 +101,17 @@ window.handleDataResponse = function(data, textStatus, jqXHR) {
|
||||
&& urlPortal !== ent[0]
|
||||
) return;
|
||||
|
||||
if('imageByUrl' in ent[2] && 'imageUrl' in ent[2].imageByUrl) {
|
||||
if(window.location.protocol === 'https:') {
|
||||
ent[2].imageByUrl.imageUrl = ent[2].imageByUrl.imageUrl.indexOf('www.panoramio.com') !== -1
|
||||
? ent[2].imageByUrl.imageUrl.replace(/^http:\/\/www/, 'https://ssl').replace('small', 'medium')
|
||||
: ent[2].imageByUrl.imageUrl.replace(/^http:\/\//, '//');
|
||||
}
|
||||
} else {
|
||||
ent[2].imageByUrl = {'imageUrl': DEFAULT_PORTAL_IMG};
|
||||
}
|
||||
|
||||
|
||||
ppp.push(ent); // delay portal render
|
||||
ppp[ent[0]] = ent; // delay portal render
|
||||
} else if(ent[2].edge !== undefined) {
|
||||
renderLink(ent);
|
||||
} else if(ent[2].capturedRegion !== undefined) {
|
||||
@ -124,6 +128,25 @@ window.handleDataResponse = function(data, textStatus, jqXHR) {
|
||||
});
|
||||
|
||||
$.each(ppp, function(ind, portal) {
|
||||
if ('portalV2' in portal[2] && 'linkedEdges' in portal[2].portalV2) {
|
||||
$.each(portal[2].portalV2.linkedEdges, function (ind, edge) {
|
||||
if (!ppp[edge.otherPortalGuid])
|
||||
return;
|
||||
renderLink([
|
||||
edge.edgeGuid,
|
||||
portal[1],
|
||||
{
|
||||
"controllingTeam": portal[2].controllingTeam,
|
||||
"edge": {
|
||||
"destinationPortalGuid": edge.isOrigin ? ppp[edge.otherPortalGuid][0] : portal[0],
|
||||
"destinationPortalLocation": edge.isOrigin ? ppp[edge.otherPortalGuid][2].locationE6 : portal[2].locationE6,
|
||||
"originPortalGuid": !edge.isOrigin ? ppp[edge.otherPortalGuid][0] : portal[0],
|
||||
"originPortalLocation": !edge.isOrigin ? ppp[edge.otherPortalGuid][2].locationE6 : portal[2].locationE6
|
||||
}
|
||||
}
|
||||
]);
|
||||
});
|
||||
}
|
||||
if(portal[2].portalV2['linkedFields'] === undefined) {
|
||||
portal[2].portalV2['linkedFields'] = [];
|
||||
}
|
||||
|
@ -1,79 +1,45 @@
|
||||
|
||||
|
||||
// MAP DATA REQUEST CALCULATORS //////////////////////////////////////
|
||||
// Ingress Intel splits up requests for map data (portals, links,
|
||||
// fields) into tiles. To get data for the current viewport (i.e. what
|
||||
// is currently visible) it first calculates which tiles intersect.
|
||||
// For all those tiles, it then calculates the lat/lng bounds of that
|
||||
// tile and a quadkey. Both the bounds and the quadkey are “somewhat”
|
||||
// required to get complete data. No idea how the projection between
|
||||
// lat/lng and tiles works.
|
||||
// What follows now are functions that allow conversion between tiles
|
||||
// and lat/lng as well as calculating the quad key. The variable names
|
||||
// may be misleading.
|
||||
// The minified source for this code was in gen_dashboard.js after the
|
||||
// “// input 89” line (alternatively: the class was called “Xe”).
|
||||
// required to get complete data.
|
||||
//
|
||||
// Convertion functions courtesy of
|
||||
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
||||
|
||||
window.convertCenterLat = function(centerLat) {
|
||||
return Math.round(256 * 0.9999 * Math.abs(1 / Math.cos(centerLat * DEG2RAD)));
|
||||
window.lngToTile = function(lng, zoom) {
|
||||
return Math.floor((lng + 180) / 360 * Math.pow(2, zoom));
|
||||
}
|
||||
|
||||
window.calculateR = function(convCenterLat) {
|
||||
return 1 << window.map.getZoom() - (convCenterLat / 256 - 1);
|
||||
window.latToTile = function(lat, zoom) {
|
||||
return Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) +
|
||||
1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom));
|
||||
}
|
||||
|
||||
window.convertLatLngToPoint = function(latlng, magic, R) {
|
||||
var x = (magic/2 + latlng.lng * magic / 360)*R;
|
||||
var l = Math.sin(latlng.lat * DEG2RAD);
|
||||
var y = (magic/2 + 0.5*Math.log((1+l)/(1-l)) * -(magic / (2*Math.PI)))*R;
|
||||
return {x: Math.floor(x/magic), y: Math.floor(y/magic)};
|
||||
window.tileToLng = function(x, zoom) {
|
||||
return x / Math.pow(2, zoom) * 360 - 180;
|
||||
}
|
||||
|
||||
window.convertPointToLatLng = function(x, y, magic, R) {
|
||||
var e = {};
|
||||
e.sw = {
|
||||
// orig function put together from all over the place
|
||||
// lat: (2 * Math.atan(Math.exp((((y + 1) * magic / R) - (magic/ 2)) / (-1*(magic / (2 * Math.PI))))) - Math.PI / 2) / (Math.PI / 180),
|
||||
// shortened version by your favorite algebra program.
|
||||
lat: (360*Math.atan(Math.exp(Math.PI - 2*Math.PI*(y+1)/R)))/Math.PI - 90,
|
||||
lng: 360*x/R-180
|
||||
};
|
||||
e.ne = {
|
||||
//lat: (2 * Math.atan(Math.exp(((y * magic / R) - (magic/ 2)) / (-1*(magic / (2 * Math.PI))))) - Math.PI / 2) / (Math.PI / 180),
|
||||
lat: (360*Math.atan(Math.exp(Math.PI - 2*Math.PI*y/R)))/Math.PI - 90,
|
||||
lng: 360*(x+1)/R-180
|
||||
};
|
||||
return e;
|
||||
window.tileToLat = function(y, zoom) {
|
||||
var n = Math.PI - 2 * Math.PI * y / Math.pow(2, zoom);
|
||||
return 180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
|
||||
}
|
||||
|
||||
// calculates the quad key for a given point. The point is not(!) in
|
||||
// lat/lng format.
|
||||
window.pointToQuadKey = function(x, y) {
|
||||
var quadkey = [];
|
||||
for(var c = window.map.getZoom(); c > 0; c--) {
|
||||
// +-------+ quadrants are probably ordered like this
|
||||
// | 0 | 1 |
|
||||
// |---|---|
|
||||
// | 2 | 3 |
|
||||
// |---|---|
|
||||
var quadrant = 0;
|
||||
var e = 1 << c - 1;
|
||||
(x & e) != 0 && quadrant++; // push right
|
||||
(y & e) != 0 && (quadrant++, quadrant++); // push down
|
||||
quadkey.push(quadrant);
|
||||
}
|
||||
return quadkey.join("");
|
||||
window.pointToTileId = function(zoom, x, y) {
|
||||
return zoom + "_" + x + "_" + y;
|
||||
}
|
||||
|
||||
// given quadkey and bounds, returns the format as required by the
|
||||
// given tile id and bounds, returns the format as required by the
|
||||
// Ingress API to request map data.
|
||||
window.generateBoundsParams = function(quadkey, bounds) {
|
||||
window.generateBoundsParams = function(tile_id, minLat, minLng, maxLat, maxLng) {
|
||||
return {
|
||||
id: quadkey,
|
||||
qk: quadkey,
|
||||
minLatE6: Math.round(bounds.sw.lat * 1E6),
|
||||
minLngE6: Math.round(bounds.sw.lng * 1E6),
|
||||
maxLatE6: Math.round(bounds.ne.lat * 1E6),
|
||||
maxLngE6: Math.round(bounds.ne.lng * 1E6)
|
||||
id: tile_id,
|
||||
qk: tile_id,
|
||||
minLatE6: Math.round(minLat * 1E6),
|
||||
minLngE6: Math.round(minLng * 1E6),
|
||||
maxLatE6: Math.round(maxLat * 1E6),
|
||||
maxLngE6: Math.round(maxLng * 1E6)
|
||||
};
|
||||
}
|
||||
|
@ -44,10 +44,7 @@ window.renderPortalDetails = function(guid) {
|
||||
var resoDetails = '<table id="resodetails">' + getResonatorDetails(d) + '</table>';
|
||||
|
||||
setPortalIndicators(d);
|
||||
var img = d.imageByUrl && d.imageByUrl.imageUrl
|
||||
? d.imageByUrl.imageUrl
|
||||
: DEFAULT_PORTAL_IMG;
|
||||
|
||||
var img = d.imageByUrl.imageUrl;
|
||||
var lat = d.locationE6.latE6;
|
||||
var lng = d.locationE6.lngE6;
|
||||
var perma = '/intel?latE6='+lat+'&lngE6='+lng+'&z=17&pguid='+guid;
|
||||
|
@ -1,7 +1,8 @@
|
||||
// UTILS + MISC ///////////////////////////////////////////////////////
|
||||
|
||||
window.aboutIITC = function(){
|
||||
var v = '@@BUILDNAME@@-@@BUILDDATE@@'
|
||||
var v = '@@BUILDNAME@@-@@BUILDDATE@@';
|
||||
var attrib = '@@INCLUDEMD:ATTRIBUTION.md@@';
|
||||
var a = ''
|
||||
+ ' <div><b>About IITC</b></div> '
|
||||
+ ' <div>Ingress Intel Total Conversion</div> '
|
||||
@ -20,8 +21,11 @@ window.aboutIITC = function(){
|
||||
+ ' MapQuest OSM tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png">'
|
||||
+ ' </div>'
|
||||
+ ' <hr>'
|
||||
+ ' <div>Version: ' + v + '</div>';
|
||||
alert(a);
|
||||
+ ' <div>Version: ' + v + '</div>'
|
||||
+ ' <hr>'
|
||||
+ ' <div>' + attrib + '</div>';
|
||||
alert(a, true, function() {$('.ui-dialog').removeClass('ui-dialog-aboutIITC');});
|
||||
$('.ui-dialog').addClass('ui-dialog-aboutIITC');
|
||||
}
|
||||
|
||||
|
||||
@ -197,8 +201,8 @@ window.renderLimitReached = function(ratio) {
|
||||
|
||||
window.getMinPortalLevel = function() {
|
||||
var z = map.getZoom();
|
||||
if(z >= 16) return 0;
|
||||
var conv = ['impossible', 8,7,7,6,6,5,5,4,4,3,3,2,2,1,1];
|
||||
if(z >= 17) return 0;
|
||||
var conv = ['impossible', 8,8,8,7,7,6,6,5,4,4,3,3,2,2,1,1];
|
||||
var minLevelByRenderLimit = portalRenderLimit.getMinLevel();
|
||||
var result = minLevelByRenderLimit > conv[z]
|
||||
? minLevelByRenderLimit
|
||||
|
4
main.js
4
main.js
@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @id ingress-intel-total-conversion@jonatkins
|
||||
// @name IITC: Ingress intel map total conversion
|
||||
// @version 0.10.5.@@DATETIMEVERSION@@
|
||||
// @version 0.11.2.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -87,7 +87,7 @@ document.getElementsByTagName('body')[0].innerHTML = ''
|
||||
+ ' <div id="gamestat"> loading global control stats</div>'
|
||||
+ ' <div id="geosearchwrapper">'
|
||||
+ ' <input id="geosearch" placeholder="Search location…" type="text"/>'
|
||||
+ ' <img src="@@INCLUDEIMAGE:images/current-location.png@@"/>'
|
||||
+ ' <img src="@@INCLUDEIMAGE:images/current-location.png@@"/ title="Current Location">'
|
||||
+ ' </div>'
|
||||
+ ' <div id="portaldetails"></div>'
|
||||
+ ' <input id="redeem" placeholder="Redeem code…" type="text"/>'
|
||||
|
1
mobile/.gitignore
vendored
1
mobile/.gitignore
vendored
@ -7,3 +7,4 @@ libs/
|
||||
proguard-project.txt
|
||||
local.properties
|
||||
assets/iitc.js
|
||||
assets/plugins/
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.cradle.iitc_mobile"
|
||||
android:versionCode="9"
|
||||
android:versionName="0.2.8" >
|
||||
android:versionCode="11"
|
||||
android:versionName="0.3" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="14"
|
||||
|
@ -1,7 +1,11 @@
|
||||
How does this basically work?
|
||||
-----------------------------
|
||||
|
||||
At the moment, the Android App is nothing more then a WebView which renders the normal web page. The IITC script is injected on page load and after this, it works the same way as on desktop browser. More functionality will be added soon...
|
||||
At the moment, the Android App is a WebView which renders the normal web page. The IITC script is injected by calling ```iitc_view.loadIITC_JS(Context)```. The app uses a local version of the script, which is located in the assets folder, if no external source is given (see "pref\_iitc\_source").
|
||||
|
||||
Communication from app to script is handled by loading Javascript function calls. For example: ```iitc_view.loadUrl("javascript: window.goBack();");```
|
||||
|
||||
Communication from script to app is handled by the JavascriptInterface (see /mobile/src/com/cradle/iitc\_mobile/IITC_JSInterface.java). If a method ```foo(String)``` is defined in JSInterface, it can be called by ```android.foo("Hello World")``` in the IITC script.
|
||||
|
||||
Debugging
|
||||
---------
|
||||
@ -16,13 +20,8 @@ Debugging IITC(M) **before** it has booted requires the Android Developer Tools.
|
||||
Building the APK
|
||||
----------------
|
||||
|
||||
- **Eclipse:** Just import this project and klick the build button.
|
||||
- **ant:**
|
||||
Set the ANDROID_HOME environment variable:
|
||||
```export ANDROID_HOME=/path/to/android_sdk```
|
||||
and build the project with ant:
|
||||
`ant debug`
|
||||
- You can use `build_mobile.js`, too, which builds IITC, compresses
|
||||
it and uses ant to build a release APK of IITCM. It requires that
|
||||
you have Python and uglifyjs installed. You need to set the
|
||||
`ANDROID_HOME`, like explained above.
|
||||
Then build the app via the build.py script ```./build.py mobile```
|
||||
- **Eclipse:** Just import this project and klick the build button. Ensure that you have iitc.js in your assets folder. This is automatically created, when executing ```./build.py mobile```. Otherwise, just copy the IITC script to the assets folder and rename it to iitc.js
|
||||
|
@ -1,6 +1,22 @@
|
||||
ingress intel total conversion (IITC)
|
||||
ingress intel total conversion mobile (IITCM)
|
||||
=====================================
|
||||
|
||||
# [User documentation moved to the wiki. Please see there!](https://github.com/breunigs/ingress-intel-total-conversion/wiki/IITC-Mobile)
|
||||
The Android App behaves like the desktop version, but uses the mobile view, which is optimized for mobile devices, as default. Furthermore, there are some nice additions:
|
||||
|
||||
### [For developer docs, please see HACKING.md](https://github.com/breunigs/ingress-intel-total-conversion/blob/gh-pages/mobile/HACKING.md)
|
||||
- it should be much faster than the standard mobile ingress intel map
|
||||
|
||||
- a gmaps intent is sent, when a portals Map link is clicked (lets you navigate to portals)
|
||||
|
||||
- a geolocate button (you have to enable GPS satellites + location access to use this feature)
|
||||
|
||||
- toggle between desktop and mobile view (nice for tablets)
|
||||
|
||||
- possibility to use a custom IITC script source
|
||||
|
||||
- a click on Portal link copies it to clipboard
|
||||
|
||||
- more features will be added soon...
|
||||
|
||||
**The App only works with Android 4.0+**
|
||||
|
||||
### [For developer docs, please see HACKING.md](https://github.com/jonatkins/ingress-intel-total-conversion/blob/master/mobile/HACKING.md)
|
||||
|
@ -32,6 +32,8 @@
|
||||
</string>
|
||||
|
||||
<string name="pref_ui_cat">UI</string>
|
||||
<string name="pref_plugins">Plugins</string>
|
||||
<string name="pref_plugins_title">Available plugins</string>
|
||||
<string name="pref_force_desktop">Force desktop mode</string>
|
||||
<string name="pref_force_desktop_sum">Nice for tablets, looks awful on smartphones</string>
|
||||
<string name="pref_developer_options">Developer options</string>
|
||||
|
@ -17,6 +17,10 @@
|
||||
android:title="@string/pref_force_desktop"
|
||||
android:summary="@string/pref_force_desktop_sum"
|
||||
android:defaultValue="false" />
|
||||
<MultiSelectListPreference
|
||||
android:key="pref_plugins"
|
||||
android:title="@string/pref_plugins"
|
||||
android:dialogTitle="@string/pref_plugins_title"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
@ -19,6 +19,14 @@ body {
|
||||
}
|
||||
|
||||
|
||||
#geosearch {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#geosearchwrapper img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#chatcontrols {
|
||||
height: 38px;
|
||||
width: 100%;
|
||||
|
@ -56,7 +56,7 @@ public class IITC_Mobile extends Activity {
|
||||
if (Intent.ACTION_VIEW.equals(action)) {
|
||||
Uri uri = intent.getData();
|
||||
String url = uri.toString();
|
||||
if (intent.getScheme().equals("http://"))
|
||||
if (intent.getScheme().equals("http"))
|
||||
url = url.replace("http://", "https://");
|
||||
Log.d("iitcm", "intent received url: " + url);
|
||||
if (url.contains("ingress.com")) {
|
||||
|
@ -1,6 +1,11 @@
|
||||
package com.cradle.iitc_mobile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class IITC_Settings extends Activity {
|
||||
@ -10,7 +15,52 @@ public class IITC_Settings extends Activity {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
IITC_SettingsFragment settings = new IITC_SettingsFragment();
|
||||
settings.setArguments(getIntent().getExtras());
|
||||
|
||||
AssetManager am = this.getAssets();
|
||||
String[] asset_array = null;
|
||||
try {
|
||||
asset_array = am.list("plugins");
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
ArrayList<String> asset_list = new ArrayList<String>();
|
||||
ArrayList<String> asset_values = new ArrayList<String>();
|
||||
|
||||
for (int i = 0; i < asset_array.length ; i++) {
|
||||
if (asset_array[i].endsWith("user.js")) {
|
||||
// find user plugin name for user readable entries
|
||||
Scanner s = null;
|
||||
String src = "";
|
||||
try {
|
||||
s = new Scanner(am.open("plugins/" + asset_array[i])).useDelimiter("\\A");
|
||||
} catch (IOException e2) {
|
||||
// TODO Auto-generated catch block
|
||||
e2.printStackTrace();
|
||||
}
|
||||
if (s != null) src = s.hasNext() ? s.next() : "";
|
||||
String header = src.substring(src.indexOf("==UserScript=="), src.indexOf("==/UserScript=="));
|
||||
// remove new line comments and replace with space
|
||||
// this way we get double spaces instead of newline + double slash
|
||||
header = header.replace("\n//", " ");
|
||||
// get a list of key-value...split on multiple spaces
|
||||
String[] attributes = header.split(" +");
|
||||
String plugin_name = "not found";
|
||||
for (int j = 0; j < attributes.length; j++) {
|
||||
// search for name and use the value
|
||||
if (attributes[j].equals("@name")) plugin_name = attributes[j+1];
|
||||
}
|
||||
asset_list.add(plugin_name);
|
||||
// real value
|
||||
asset_values.add(asset_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Bundle bundle = getIntent().getExtras();
|
||||
bundle.putStringArray("ASSETS", (String[]) asset_list.toArray(new String[0]));
|
||||
bundle.putStringArray("ASSETS_VAL", (String[]) asset_values.toArray(new String[0]));
|
||||
settings.setArguments(bundle);
|
||||
|
||||
// Display the fragment as the main content.
|
||||
getFragmentManager().beginTransaction()
|
||||
|
@ -6,6 +6,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.Bundle;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.MultiSelectListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.preference.PreferenceFragment;
|
||||
@ -21,7 +22,12 @@ public class IITC_SettingsFragment extends PreferenceFragment {
|
||||
iitc_version = getArguments().getString("iitc_version");
|
||||
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
|
||||
//plugins
|
||||
MultiSelectListPreference pref_plugins = (MultiSelectListPreference) findPreference("pref_plugins");
|
||||
pref_plugins.setEntries(getArguments().getStringArray("ASSETS"));
|
||||
pref_plugins.setEntryValues(getArguments().getStringArray("ASSETS_VAL"));
|
||||
|
||||
// set build version
|
||||
ListPreference pref_build_version = (ListPreference) findPreference("pref_build_version");
|
||||
PackageManager pm = getActivity().getPackageManager();
|
||||
|
@ -3,6 +3,7 @@ package com.cradle.iitc_mobile;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.AssetManager;
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslError;
|
||||
import android.preference.PreferenceManager;
|
||||
@ -17,6 +18,7 @@ import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
|
||||
public class IITC_WebViewClient extends WebViewClient {
|
||||
private static final ByteArrayInputStream style = new ByteArrayInputStream(
|
||||
@ -44,7 +46,7 @@ public class IITC_WebViewClient extends WebViewClient {
|
||||
String[] attributes = header.split(" +");
|
||||
String iitc_version = "not found";
|
||||
for (int i = 0; i < attributes.length; i++) {
|
||||
// search vor version and use the value
|
||||
// search for version and use the value
|
||||
if (attributes[i].equals("@version")) iitc_version = attributes[i+1];
|
||||
}
|
||||
return iitc_version;
|
||||
@ -91,6 +93,39 @@ public class IITC_WebViewClient extends WebViewClient {
|
||||
handler.proceed() ;
|
||||
};
|
||||
|
||||
// plugins should be loaded after the main script is injected
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
super.onPageFinished(view, url);
|
||||
|
||||
// get the plugin preferences
|
||||
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
Set<String> plugin_list = sharedPref.getStringSet("pref_plugins", null);
|
||||
|
||||
// iterate through all enabled plugins and load them
|
||||
if (plugin_list != null) {
|
||||
AssetManager am = context.getAssets();
|
||||
String[] plugin_array = plugin_list.toArray(new String[0]);
|
||||
|
||||
for(int i = 0; i < plugin_list.size(); i++) {
|
||||
if (plugin_array[i].endsWith("user.js"));
|
||||
{
|
||||
Log.d("iitcm", "adding plugin " + plugin_array[i]);
|
||||
Scanner s = null;
|
||||
String src = "";
|
||||
try {
|
||||
s = new Scanner(am.open("plugins/" + plugin_array[i])).useDelimiter("\\A");
|
||||
} catch (IOException e2) {
|
||||
// TODO Auto-generated catch block
|
||||
e2.printStackTrace();
|
||||
}
|
||||
if (s != null) src = s.hasNext() ? s.next() : "";
|
||||
view.loadUrl("javascript:" + src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check every external resource if it’s okay to load it and maybe replace it
|
||||
// with our own content. This is used to block loading Niantic resources
|
||||
// which aren’t required and to inject IITC early into the site.
|
||||
@ -119,6 +154,11 @@ public class IITC_WebViewClient extends WebViewClient {
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
if (url.contains("ingress.com")) {
|
||||
// reload iitc if a poslink is clicked inside the app
|
||||
if (url.contains("intel?ll=") || (url.contains("latE6") && url.contains("lngE6"))) {
|
||||
Log.d("iitcm", "should be an internal clicked position link...reload script for: " + url);
|
||||
((IITC_Mobile) context).loadUrl(url);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
Log.d("iitcm", "no ingress intel link, start external app to load url: " + url);
|
||||
|
@ -1,11 +1,11 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-ap-list@xelio
|
||||
// @name IITC plugin: AP List
|
||||
// @version 0.5.1.@@DATETIMEVERSION@@
|
||||
// @version 0.5.2.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] List top 10 portals by AP of either faction. Other functions and controls please refer to the Userguide.
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] List portals by AP of either faction or by effective level. Other functions and controls please refer to the Userguide.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
|
@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-ipas-link@graphracer
|
||||
// @name IITC Plugin: simulate an attack on portal
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @version 0.2.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/xosofox/IPAS
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
@ -30,16 +30,34 @@ window.plugin.ipasLink.addLink = function(d) {
|
||||
$('.linkdetails').append('<aside><a href="http://ipas.graphracer.com/index.html#' + window.plugin.ipasLink.getHash(d.portalDetails) + '" target="ipaswindow" title="Use IAPS to simulate an attack on this portal">Simulate attack</a></aside>');
|
||||
}
|
||||
|
||||
window.plugin.ipasLink.getHash = function(d) {
|
||||
var hashParts=[];
|
||||
$.each(d.resonatorArray.resonators, function(ind, reso) {
|
||||
if (reso) {
|
||||
hashParts.push(reso.level + "," + reso.distanceToPortal + "," + reso.energyTotal);
|
||||
} else {
|
||||
hashParts.push(1 + "," + 35 + "," + 0); // Dummy values, the only important one is energy=0
|
||||
}
|
||||
});
|
||||
return hashParts.join(";")+"|" + "0,0,0,0"; //shields not implemented yet
|
||||
window.plugin.ipasLink.getHash = function (d) {
|
||||
var hashParts = [];
|
||||
$.each(d.resonatorArray.resonators, function (ind, reso) {
|
||||
if (reso) {
|
||||
hashParts.push(reso.level + "," + reso.distanceToPortal + "," + reso.energyTotal);
|
||||
} else {
|
||||
hashParts.push("1,20,0");
|
||||
}
|
||||
});
|
||||
var resos = hashParts.join(";");
|
||||
|
||||
hashParts = [];
|
||||
$.each(d.portalV2.linkedModArray, function (ind, mod) {
|
||||
//shields only, so far...
|
||||
var s = "0";
|
||||
if (mod) {
|
||||
if (mod.type === "RES_SHIELD") {
|
||||
s = mod.rarity.charAt(0).toLowerCase();
|
||||
}
|
||||
}
|
||||
hashParts.push(s);
|
||||
});
|
||||
var shields = hashParts.join(",");
|
||||
return resos + "|" + shields;
|
||||
}
|
||||
|
||||
var setup = function () {
|
||||
window.plugin.ipasLink.setupCallback();
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
|
@ -266,12 +266,13 @@ window.plugin.playerTracker.drawData = function() {
|
||||
if(window.plugin.guessPlayerLevels !== undefined &&
|
||||
window.plugin.guessPlayerLevels.fetchLevelByPlayer !== undefined) {
|
||||
var playerLevel = window.plugin.guessPlayerLevels.fetchLevelByPlayer(pguid);
|
||||
if (playerLevel === undefined) playerLevel = 1; //if player level unknown, assume level 1
|
||||
if(playerLevel !== undefined) {
|
||||
title += '<span style="font-weight:bold;margin-left:10px;">Level '
|
||||
+ playerLevel
|
||||
+ (playerLevel < (window.MAX_XM_PER_LEVEL.length - 1) ? ' (guessed)' : '')
|
||||
+ '</span>';
|
||||
} else {
|
||||
title += '<span style="font-weight:bold;margin-left:10px;">Level unknown</span>'
|
||||
}
|
||||
}
|
||||
|
||||
|
51
plugins/portal-highlighter-level-color.user.js
Normal file
51
plugins/portal-highlighter-level-color.user.js
Normal file
@ -0,0 +1,51 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-level-color@vita10gy
|
||||
// @name IITC plugin: highlight portals by level color
|
||||
// @version 0.1.0.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals level color.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// ==/UserScript==
|
||||
|
||||
function wrapper() {
|
||||
// ensure plugin framework is there, even if iitc is not yet loaded
|
||||
if(typeof window.plugin !== 'function') window.plugin = function() {};
|
||||
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
// use own namespace for plugin
|
||||
|
||||
window.plugin.portalHighligherPortalsLevelColor = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalsLevelColor.colorLevel = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var portal_level = Math.floor(getPortalLevel(d));
|
||||
var opacity = .6;
|
||||
data.portal.setStyle({fillColor: COLORS_LVL[portal_level], fillOpacity: opacity});
|
||||
window.COLOR_SELECTED_PORTAL = '#f0f';
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Level Color', window.plugin.portalHighligherPortalsLevelColor.colorLevel);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
if(window.iitcLoaded && typeof setup === 'function') {
|
||||
setup();
|
||||
} else {
|
||||
if(window.bootPlugins)
|
||||
window.bootPlugins.push(setup);
|
||||
else
|
||||
window.bootPlugins = [setup];
|
||||
}
|
||||
} // wrapper end
|
||||
// inject code into site context
|
||||
var script = document.createElement('script');
|
||||
script.appendChild(document.createTextNode('('+ wrapper +')();'));
|
||||
(document.body || document.head || document.documentElement).appendChild(script);
|
118
plugins/portal-highlighter-portal-ap-energy-relative.user.js
Normal file
118
plugins/portal-highlighter-portal-ap-energy-relative.user.js
Normal file
@ -0,0 +1,118 @@
|
||||
// ==UserScript==
|
||||
// @id iitc-plugin-highlight-portals-by-ap-by-energy-relative@vita10gy
|
||||
// @name IITC plugin: highlight portals by ap/energy (relative)
|
||||
// @version 0.1.1.@@DATETIMEVERSION@@
|
||||
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
|
||||
// @updateURL @@UPDATEURL@@
|
||||
// @downloadURL @@DOWNLOADURL@@
|
||||
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote AP/Energy value relative to what's currently on the screen. Brighter is better. Orange means your standard 8 down 8 up swap.
|
||||
// @include https://www.ingress.com/intel*
|
||||
// @include http://www.ingress.com/intel*
|
||||
// @match https://www.ingress.com/intel*
|
||||
// @match http://www.ingress.com/intel*
|
||||
// ==/UserScript==
|
||||
|
||||
function wrapper() {
|
||||
// ensure plugin framework is there, even if iitc is not yet loaded
|
||||
if(typeof window.plugin !== 'function') window.plugin = function() {};
|
||||
|
||||
|
||||
// PLUGIN START ////////////////////////////////////////////////////////
|
||||
|
||||
// use own namespace for plugin
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative = function() {};
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP = null;
|
||||
//This is the AP for a run of the mill takedown/putback
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.baseSwapAP = 2350;
|
||||
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.highlight = function(data) {
|
||||
var d = data.portal.options.details;
|
||||
var color = 'red';
|
||||
|
||||
if(window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP == null ||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP == null) {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.calculateAPLevels();
|
||||
}
|
||||
var minApE = window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP;
|
||||
var maxApE = window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP;
|
||||
|
||||
if(PLAYER.team !== d.controllingTeam.team) {
|
||||
var ap = getAttackApGain(d);
|
||||
var energy = getCurrentPortalEnergy(d);
|
||||
if(energy < 1) {
|
||||
energy = 1;
|
||||
}
|
||||
portal_ap = ap.enemyAp;
|
||||
|
||||
var opacity = 1;
|
||||
if(minApE !== maxApE) {
|
||||
opacity = ((ap.enemyAp / energy) - minApE) / (maxApE - minApE);
|
||||
}
|
||||
|
||||
if(opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
if(opacity > 1) {
|
||||
opacity = 1;
|
||||
}
|
||||
data.portal.setStyle({fillColor: color, fillOpacity: opacity});
|
||||
window.COLOR_SELECTED_PORTAL = '#f0f';
|
||||
}
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.resetAPLevels = function() {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP = null;
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP = null;
|
||||
}
|
||||
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.calculateAPLevels = function() {
|
||||
var displayBounds = map.getBounds();
|
||||
$.each(window.portals, function(qk, portal) {
|
||||
if(displayBounds.contains(portal.getLatLng())) {
|
||||
if(PLAYER.team !== portal.options.details.controllingTeam.team) {
|
||||
var ap = getAttackApGain(portal.options.details);
|
||||
var energy = getCurrentPortalEnergy(portal.options.details);
|
||||
if(energy < 1) {
|
||||
energy = 1;
|
||||
}
|
||||
var portal_ap = ap.enemyAp / energy;
|
||||
if(window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP === null ||
|
||||
portal_ap < window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP) {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.minAP = portal_ap;
|
||||
}
|
||||
if(window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP === null ||
|
||||
portal_ap > window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP) {
|
||||
window.plugin.portalHighligherPortalAPPerEnergyRelative.maxAP = portal_ap;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('AP/Energy (Relative)', window.plugin.portalHighligherPortalAPPerEnergyRelative.highlight);
|
||||
window.addHook('requestFinished', window.plugin.portalHighligherPortalAPPerEnergyRelative.resetAPLevels);
|
||||
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
||||
if(window.iitcLoaded && typeof setup === 'function') {
|
||||
setup();
|
||||
} else {
|
||||
if(window.bootPlugins)
|
||||
window.bootPlugins.push(setup);
|
||||
else
|
||||
window.bootPlugins = [setup];
|
||||
}
|
||||
} // wrapper end
|
||||
// inject code into site context
|
||||
var script = document.createElement('script');
|
||||
script.appendChild(document.createTextNode('('+ wrapper +')();'));
|
||||
(document.body || document.head || document.documentElement).appendChild(script);
|
@ -90,10 +90,8 @@ window.plugin.portalHighligherPortalAPRelative.calculateAPLevels = function() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Portal AP (Relative)', window.plugin.portalHighligherPortalAPRelative.highlight);
|
||||
window.addPortalHighlighter('AP (Relative)', window.plugin.portalHighligherPortalAPRelative.highlight);
|
||||
window.addHook('requestFinished', window.plugin.portalHighligherPortalAPRelative.resetAPLevels);
|
||||
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ window.plugin.portalHighligherPortalAP.highlight = function(data) {
|
||||
}
|
||||
|
||||
var setup = function() {
|
||||
window.addPortalHighlighter('Portal AP', window.plugin.portalHighligherPortalAP.highlight);
|
||||
window.addPortalHighlighter('AP (Static)', window.plugin.portalHighligherPortalAP.highlight);
|
||||
}
|
||||
|
||||
// PLUGIN END //////////////////////////////////////////////////////////
|
||||
|
@ -28,7 +28,7 @@ window.plugin.scaleBar.setup = function() {
|
||||
// Before you ask: yes, I explicitely turned off imperial units. Imperial units
|
||||
// are worse than Internet Explorer 6 whirring fans combined. Upgrade to the metric
|
||||
// system already.
|
||||
window.map.addControl(new L.Control.Scale({position: 'topleft', imperial: false}));
|
||||
window.map.addControl(new L.Control.Scale({position: 'topleft', imperial: false, maxWidth: 200}));
|
||||
};
|
||||
|
||||
var setup = window.plugin.scaleBar.setup;
|
||||
|
@ -71,9 +71,18 @@ window.plugin.showLinkedPortal.getPortalByGuid = function (guid) {
|
||||
var portalDetails = window.portals[guid].options.details;
|
||||
portalInfoString = '';
|
||||
var portalNameAdressAlt = "'" + portalDetails.portalV2.descriptiveText.TITLE + "' (" + portalDetails.portalV2.descriptiveText.ADDRESS + ")";
|
||||
var portalNameAdressTitle = "'<strong>" + portalDetails.portalV2.descriptiveText.TITLE + "</strong>'<br/> <em>(" + portalDetails.portalV2.descriptiveText.ADDRESS + ")</em>";
|
||||
var portalNameAdressTitle = $('<div/>').append('\'')
|
||||
.append($('<strong/>').text(portalDetails.portalV2.descriptiveText.TITLE))
|
||||
.append('\'')
|
||||
.append($('<br/>'))
|
||||
.append($('<em/>').text('(' + portalDetails.portalV2.descriptiveText.ADDRESS + ')'))
|
||||
.html();
|
||||
var imageUrl = (portalDetails.imageByUrl ? portalDetails.imageByUrl.imageUrl : window.DEFAULT_PORTAL_IMG);
|
||||
portalInfoString = '<img src="' + imageUrl + '" class="minImg" alt="' + portalNameAdressAlt + '" title="' + portalNameAdressTitle + '"/>';
|
||||
portalInfoString = $('<div/>').html($('<img/>').attr('src', imageUrl)
|
||||
.attr('class', 'minImg')
|
||||
.attr('alt', portalNameAdressAlt)
|
||||
.attr('title', portalNameAdressTitle))
|
||||
.html();
|
||||
}
|
||||
return portalInfoString;
|
||||
};
|
||||
|
13
style.css
13
style.css
@ -68,6 +68,10 @@ body {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #ffce00;
|
||||
cursor: pointer;
|
||||
@ -434,6 +438,7 @@ input {
|
||||
#geosearchwrapper img{
|
||||
vertical-align: bottom;
|
||||
margin-bottom: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
::-webkit-input-placeholder {
|
||||
font-style: italic;
|
||||
@ -691,9 +696,8 @@ h3 {
|
||||
}
|
||||
#largepreview img {
|
||||
box-shadow: 0 0 40px #000;
|
||||
}
|
||||
#largepreview img {
|
||||
border: 2px solid #f8ff5e;
|
||||
background-color: rgba(8, 48, 78, 0.9); /* as some images - eg ZipCar - have transparency */
|
||||
}
|
||||
|
||||
/* tooltips, dialogs */
|
||||
@ -762,6 +766,11 @@ h3 {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.ui-dialog-aboutIITC {
|
||||
max-width: 600px !important;
|
||||
width: 600px !important;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
|
Loading…
x
Reference in New Issue
Block a user