From 03da82b34e94ac10b6d6ea2403a090326d5b2125 Mon Sep 17 00:00:00 2001 From: boombuler Date: Wed, 27 Feb 2013 13:04:30 +0100 Subject: [PATCH 01/37] add "nickname" class to all nicknames within the page --- code/chat.js | 2 +- code/portal_detail_display.js | 1 + code/portal_detail_display_tools.js | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/code/chat.js b/code/chat.js index 6faea140..153c5105 100644 --- a/code/chat.js +++ b/code/chat.js @@ -347,7 +347,7 @@ window.chat.renderMsg = function(msg, nick, time, team) { var s = 'style="color:'+COLORS[team]+'"'; var title = nick.length >= 8 ? 'title="'+nick+'" class="help"' : ''; var i = ['<', '>']; - return ''+t+''+i[0]+''+nick+''+i[1]+''+msg+''; + return ''+t+''+i[0]+''+nick+''+i[1]+''+msg+''; } diff --git a/code/portal_detail_display.js b/code/portal_detail_display.js index e73a664a..15dd160e 100644 --- a/code/portal_detail_display.js +++ b/code/portal_detail_display.js @@ -24,6 +24,7 @@ window.renderPortalDetails = function(guid) { var player = d.captured && d.captured.capturingPlayerId ? getPlayerName(d.captured.capturingPlayerId) : null; + player = ''+player+''; var playerText = player ? ['owner', player] : null; var time = d.captured diff --git a/code/portal_detail_display_tools.js b/code/portal_detail_display_tools.js index 2861edf7..9a50e1b7 100644 --- a/code/portal_detail_display_tools.js +++ b/code/portal_detail_display_tools.js @@ -132,6 +132,7 @@ window.renderResonatorDetails = function(slot, level, nrg, dist, nick) { var meter = '' + fill + lbar + ''; } + nick = ''+nick+''; return [meter, nick || '']; } From 1f85d1f8b2f9d86b028cff928cd8242f628d3683 Mon Sep 17 00:00:00 2001 From: Stefan Breunig Date: Sat, 2 Mar 2013 00:41:38 +0100 Subject: [PATCH 02/37] most likely fix #355 (thanks @yoshimo) --- dist/leaflet_google.js | 1 + external/leaflet_google.js | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/leaflet_google.js b/dist/leaflet_google.js index 37d6dd8c..85dfef08 100644 --- a/dist/leaflet_google.js +++ b/dist/leaflet_google.js @@ -12,6 +12,7 @@ L.Google = L.Class.extend({ errorTileUrl: '', attribution: '', opacity: 1, + tilt: 0, continuousWorld: false, noWrap: false, }, diff --git a/external/leaflet_google.js b/external/leaflet_google.js index 37d6dd8c..034fb1bc 100644 --- a/external/leaflet_google.js +++ b/external/leaflet_google.js @@ -11,6 +11,7 @@ L.Google = L.Class.extend({ subdomains: 'abc', errorTileUrl: '', attribution: '', + tilt: 0, opacity: 1, continuousWorld: false, noWrap: false, From 064f55d40d94fe5929247fc5039b3689acf456eb Mon Sep 17 00:00:00 2001 From: Stefan Breunig Date: Sat, 2 Mar 2013 00:55:25 +0100 Subject: [PATCH 03/37] really fix #355 previous patch added the option to the wrong hash --- dist/leaflet_google.js | 2 +- external/leaflet_google.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/leaflet_google.js b/dist/leaflet_google.js index 85dfef08..e59c362f 100644 --- a/dist/leaflet_google.js +++ b/dist/leaflet_google.js @@ -12,7 +12,6 @@ L.Google = L.Class.extend({ errorTileUrl: '', attribution: '', opacity: 1, - tilt: 0, continuousWorld: false, noWrap: false, }, @@ -93,6 +92,7 @@ L.Google = L.Class.extend({ var map = new google.maps.Map(this._container, { center: this._google_center, zoom: 0, + tilt: 0, styles: this._styles, mapTypeId: this._type, disableDefaultUI: true, diff --git a/external/leaflet_google.js b/external/leaflet_google.js index 034fb1bc..ac5b9096 100644 --- a/external/leaflet_google.js +++ b/external/leaflet_google.js @@ -11,7 +11,6 @@ L.Google = L.Class.extend({ subdomains: 'abc', errorTileUrl: '', attribution: '', - tilt: 0, opacity: 1, continuousWorld: false, noWrap: false, @@ -94,6 +93,7 @@ L.Google = L.Class.extend({ center: this._google_center, zoom: 0, styles: this._styles, + tilt: 0, mapTypeId: this._type, disableDefaultUI: true, keyboardShortcuts: false, From 4788e1119e05e7ba1733434fbffec9e35796984d Mon Sep 17 00:00:00 2001 From: Stefan Breunig Date: Sat, 2 Mar 2013 01:11:02 +0100 Subject: [PATCH 04/37] prevent LeafletGoogle from always triggering the resize event on GoogleMaps. This is broken upstream, too, but the author of the project has been unresponsive for the past half year. --- dist/leaflet_google.js | 4 ++-- external/leaflet_google.js | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dist/leaflet_google.js b/dist/leaflet_google.js index e59c362f..36d6710e 100644 --- a/dist/leaflet_google.js +++ b/dist/leaflet_google.js @@ -139,8 +139,8 @@ L.Google = L.Class.extend({ _resize: function() { var size = this._map.getSize(); - if (this._container.style.width == size.x && - this._container.style.height == size.y) + if (parseInt(this._container.style.width) == size.x && + parseInt(this._container.style.height) == size.y) return; this._container.style.width = size.x + 'px'; this._container.style.height = size.y + 'px'; diff --git a/external/leaflet_google.js b/external/leaflet_google.js index ac5b9096..c4c323e9 100644 --- a/external/leaflet_google.js +++ b/external/leaflet_google.js @@ -139,11 +139,13 @@ L.Google = L.Class.extend({ _resize: function() { var size = this._map.getSize(); - if (this._container.style.width == size.x && - this._container.style.height == size.y) + if (parseInt(this._container.style.width) == size.x && + parseInt(this._container.style.height) == size.y) return; + this._container.style.width = size.x + 'px'; this._container.style.height = size.y + 'px'; + google.maps.event.trigger(this._google, "resize"); }, From e0fbff28265127d7c09b6944206e1cbc030ceb5f Mon Sep 17 00:00:00 2001 From: Stefan Breunig Date: Sat, 2 Mar 2013 01:52:32 +0100 Subject: [PATCH 05/37] =?UTF-8?q?-=20disable=20Leaflet=E2=80=99s=20zoom=20?= =?UTF-8?q?animation=20for=20GMaps=20Layers.=20It=20was=20wrong=20=20=20an?= =?UTF-8?q?yway=20and=20due=20to=20the=20way=20Leaflet/GMaps=20worked,=20l?= =?UTF-8?q?atter=20only=20=20=20started=20zooming=20after=20former=20was?= =?UTF-8?q?=20finished,=20making=20zooming=20very=20=20=20slow.=20This=20i?= =?UTF-8?q?s=20an=20experimental=20change.=20Please=20report=20if=20you=20?= =?UTF-8?q?have=20=20=20problems.=20-=20remove=20superfluous=20calls=20in?= =?UTF-8?q?=20LeafletGoogle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- external/leaflet_google.js | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/external/leaflet_google.js b/external/leaflet_google.js index c4c323e9..d25c7f36 100644 --- a/external/leaflet_google.js +++ b/external/leaflet_google.js @@ -36,12 +36,11 @@ L.Google = L.Class.extend({ this._initContainer(); this._initMapObject(); - // set up events - map.on('viewreset', this._resetCallback, this); + this._map.options.zoomAnimation = false; - this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this); + // set up events + //~ map.on('viewreset', this._resetCallback, this); map.on('move', this._update, this); - //map.on('moveend', this._update, this); this._reset(); this._update(); @@ -51,7 +50,8 @@ L.Google = L.Class.extend({ this._map._container.removeChild(this._container); //this._container = null; - this._map.off('viewreset', this._resetCallback, this); + //~ this._map.off('viewreset', this._resetCallback, this); + this._map.options.zoomAnimation = true; this._map.off('move', this._update, this); //this._map.off('moveend', this._update, this); @@ -122,19 +122,11 @@ L.Google = L.Class.extend({ _update: function() { this._resize(); - var bounds = this._map.getBounds(); - var ne = bounds.getNorthEast(); - var sw = bounds.getSouthWest(); - var google_bounds = new google.maps.LatLngBounds( - new google.maps.LatLng(sw.lat, sw.lng), - new google.maps.LatLng(ne.lat, ne.lng) - ); var center = this._map.getCenter(); var _center = new google.maps.LatLng(center.lat, center.lng); this._google.setCenter(_center); this._google.setZoom(this._map.getZoom()); - //this._google.fitBounds(google_bounds); }, _resize: function() { From 75dea672f32b56bbb9d3dc896b326384695e0e51 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 05:56:29 -0800 Subject: [PATCH 06/37] Inital stab at mu counts for fields Still needs work on when not to display, maybe based on field area and zoom level? --- code/map_data.js | 40 ++++++++++++++++++++++++++++++++-------- style.css | 9 +++++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 363240c4..2366b533 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -179,10 +179,13 @@ window.cleanUp = function() { cnt[1]++; linksLayer.removeLayer(link); }); - fieldsLayer.eachLayer(function(field) { - if(b.intersects(field.getBounds())) return; - cnt[2]++; - fieldsLayer.removeLayer(field); + fieldsLayer.eachLayer(function(fieldgroup) { + fieldgroup.eachLayer(function(item) { + if(!item.options.guid) return true; + if(b.intersects(item.getBounds())) return; + cnt[2]++; + fieldsLayer.removeLayer(fieldgroup); + }); }); console.log('removed out-of-bounds: '+cnt[0]+' portals, '+cnt[1]+' links, '+cnt[2]+' fields'); } @@ -537,8 +540,6 @@ window.renderField = function(ent) { stroke: false, clickable: false, smoothFactor: 0, // hiding small fields will be handled below - vertices: reg, - lastUpdate: ent[1], guid: ent[0]}); // determine which fields are too small to be rendered and don’t @@ -553,14 +554,37 @@ window.renderField = function(ent) { if(!getPaddedBounds().intersects(poly.getBounds())) return; + var centroid = [ + (latlngs[0].lat + latlngs[1].lat + latlngs[2].lat)/3, + (latlngs[0].lng + latlngs[1].lng + latlngs[2].lng)/3 + ]; + + var fieldMu = L.marker(centroid, { + icon: L.divIcon({ + className: 'fieldmu', + iconSize: [100,12], + html: 'MU: ' + ent[2].entityScore.entityScore}), + clickable: false + }); + + // put both in one group, so they can be handled by the same logic. + var f = L.layerGroup([poly, fieldMu], { + vertices: reg, + lastUpdate: ent[1], + guid: ent[0]}); + + // However, LayerGroups (and FeatureGroups) don’t fire add/remove + // events, thus this listener will be attached to the field. It + // doesn’t matter to which element these are bound since Leaflet + // will add/remove all elements of the LayerGroup at once. poly.on('remove', function() { delete window.fields[this.options.guid]; }); poly.on('add', function() { // enable for debugging if(window.fields[this.options.guid]) console.warn('duplicate field detected'); - window.fields[this.options.guid] = this; + window.fields[this.options.guid] = f; this.bringToBack(); }); - poly.addTo(fieldsLayer); + f.addTo(fieldsLayer); } diff --git a/style.css b/style.css index 3ebf08bc..39d6cc49 100644 --- a/style.css +++ b/style.css @@ -93,6 +93,15 @@ a:hover { width: 0; } +/* field mu count */ + +.fieldmu { + color: #FFCE00; + font-size:13px; + font-family: "coda",arial,helvetica,sans-serif; /*override leaflet-container */ + text-align: center; +} + /* chat ***************************************************************/ From 1e21bbb94d0d9c5e4311634045da79751604aa5b Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 06:29:35 -0800 Subject: [PATCH 07/37] Add thousands separator and bug fix --- code/map_data.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 2366b533..2731ff1a 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -563,15 +563,17 @@ window.renderField = function(ent) { icon: L.divIcon({ className: 'fieldmu', iconSize: [100,12], - html: 'MU: ' + ent[2].entityScore.entityScore}), + html: 'MU: ' + digits(ent[2].entityScore.entityScore)}), clickable: false }); // put both in one group, so they can be handled by the same logic. - var f = L.layerGroup([poly, fieldMu], { + var f = L.layerGroup([poly, fieldMu]); + f.options = { vertices: reg, lastUpdate: ent[1], - guid: ent[0]}); + guid: ent[0] + }; // However, LayerGroups (and FeatureGroups) don’t fire add/remove // events, thus this listener will be attached to the field. It From c06682b9911774eed04d55548e6c7756156aefcf Mon Sep 17 00:00:00 2001 From: sutepasu Date: Sat, 2 Mar 2013 23:18:39 +0700 Subject: [PATCH 08/37] Adding total level, total player and average level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding total level, total player and average level on each faction. Adding line feed  and removing one tab on line 111 so the output will be properly generated. --- plugins/guess-player-levels.user.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/guess-player-levels.user.js b/plugins/guess-player-levels.user.js index c220a76d..02a33858 100644 --- a/plugins/guess-player-levels.user.js +++ b/plugins/guess-player-levels.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @id iitc-plugin-guess-player-levels@breunigs // @name iitc: guess player level -// @version 0.2.1 +// @version 0.2.1.1 // @namespace https://github.com/breunigs/ingress-intel-total-conversion // @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/guess-player-levels.user.js // @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/guess-player-levels.user.js @@ -92,19 +92,29 @@ window.plugin.guessPlayerLevels.guess = function() { var namesR = plugin.guessPlayerLevels.sort(playersRes); var namesE = plugin.guessPlayerLevels.sort(playersEnl); + var totallvlR = 0; + var totallvlE = 0; var max = Math.max(namesR.length, namesE.length); for(var i = 0; i < max; i++) { var nickR = namesR[i]; var lvlR = playersRes[nickR]; var lineR = nickR ? nickR + ':\t' + lvlR : '\t'; - + if(!isNaN(parseInt(lvlR))) + totallvlR += parseInt(lvlR); + var nickE = namesE[i]; var lvlE = playersEnl[nickE]; var lineE = nickE ? nickE + ':\t' + lvlE : '\t'; - - s += lineR + '\t\t' + lineE + '\n'; + if(!isNaN(parseInt(lvlE))) + totallvlE += parseInt(lvlE); + + s += '\n'+lineR + '\t' + lineE + '\n'; } - + s += '\nTotal level :\t'+totallvlR+'\tTotal level :\t'+totallvlE; + s += '\nTotal player:\t'+namesR.length+'\tTotal player:\t'+namesE.length; + var averageR = (totallvlR/namesR.length); + var averageE = (totallvlE/namesE.length); + s += '\nAverage :\t'+averageR.toFixed(2)+'\tAverage :\t'+averageE.toFixed(2); s += '\n\nIf there are some unresolved names, simply try again.' console.log(s); alert(s); From 420ec8de16296eb524bb7665a9a24b8e6a554143 Mon Sep 17 00:00:00 2001 From: vita10gy Date: Sat, 2 Mar 2013 10:23:38 -0600 Subject: [PATCH 09/37] Save Game info with links and fields Useful for plugins/extending --- code/map_data.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index b7afe533..c56bb252 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -507,9 +507,9 @@ window.renderLink = function(ent) { weight:2, clickable: false, guid: ent[0], + data: ent[2], smoothFactor: 0 // doesn’t work for two points anyway, so disable }); - // determine which links are very short and don’t render them at all. // in most cases this will go unnoticed, but improve rendering speed. poly._map = window.map; @@ -557,8 +557,9 @@ window.renderField = function(ent) { smoothFactor: 0, // hiding small fields will be handled below vertices: reg, lastUpdate: ent[1], - guid: ent[0]}); - + guid: ent[0], + data: ent[2]}); + // determine which fields are too small to be rendered and don’t // render them, so they don’t count towards the maximum fields limit. // This saves some DOM operations as well, but given the relatively From 8067d2011780bdb33b17cb533ee0d524555f5064 Mon Sep 17 00:00:00 2001 From: sutepasu Date: Sun, 3 Mar 2013 02:39:25 +0700 Subject: [PATCH 10/37] v0.3, fix divide-by-zero, change tabs to space --- plugins/guess-player-levels.user.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/plugins/guess-player-levels.user.js b/plugins/guess-player-levels.user.js index 02a33858..cfe2f94f 100644 --- a/plugins/guess-player-levels.user.js +++ b/plugins/guess-player-levels.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @id iitc-plugin-guess-player-levels@breunigs // @name iitc: guess player level -// @version 0.2.1.1 +// @version 0.3 // @namespace https://github.com/breunigs/ingress-intel-total-conversion // @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/guess-player-levels.user.js // @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/guess-player-levels.user.js @@ -99,21 +99,22 @@ window.plugin.guessPlayerLevels.guess = function() { var nickR = namesR[i]; var lvlR = playersRes[nickR]; var lineR = nickR ? nickR + ':\t' + lvlR : '\t'; - if(!isNaN(parseInt(lvlR))) - totallvlR += parseInt(lvlR); - + if(!isNaN(parseInt(lvlR))) + totallvlR += parseInt(lvlR); + var nickE = namesE[i]; var lvlE = playersEnl[nickE]; var lineE = nickE ? nickE + ':\t' + lvlE : '\t'; - if(!isNaN(parseInt(lvlE))) - totallvlE += parseInt(lvlE); - + if(!isNaN(parseInt(lvlE))) + totallvlE += parseInt(lvlE); + s += '\n'+lineR + '\t' + lineE + '\n'; } s += '\nTotal level :\t'+totallvlR+'\tTotal level :\t'+totallvlE; s += '\nTotal player:\t'+namesR.length+'\tTotal player:\t'+namesE.length; - var averageR = (totallvlR/namesR.length); - var averageE = (totallvlE/namesE.length); + var averageR = 0, averageE = 0; + if (namesR.length > 0) averageR = (totallvlR/namesR.length); + if (namesE.length > 0) averageE = (totallvlE/namesE.length); s += '\nAverage :\t'+averageR.toFixed(2)+'\tAverage :\t'+averageE.toFixed(2); s += '\n\nIf there are some unresolved names, simply try again.' console.log(s); From 612006a7d6ff5d8fcfa6147eaa1ee360520cbb1e Mon Sep 17 00:00:00 2001 From: sutepasu Date: Sun, 3 Mar 2013 02:52:21 +0700 Subject: [PATCH 11/37] Change label 'Average' to --- plugins/guess-player-levels.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/guess-player-levels.user.js b/plugins/guess-player-levels.user.js index cfe2f94f..cd77945b 100644 --- a/plugins/guess-player-levels.user.js +++ b/plugins/guess-player-levels.user.js @@ -115,7 +115,7 @@ window.plugin.guessPlayerLevels.guess = function() { var averageR = 0, averageE = 0; if (namesR.length > 0) averageR = (totallvlR/namesR.length); if (namesE.length > 0) averageE = (totallvlE/namesE.length); - s += '\nAverage :\t'+averageR.toFixed(2)+'\tAverage :\t'+averageE.toFixed(2); + s += '\nAverage level:\t'+averageR.toFixed(2)+'\tAverage level:\t'+averageE.toFixed(2); s += '\n\nIf there are some unresolved names, simply try again.' console.log(s); alert(s); From 0ba8631b82e30bff164f4f4af6bd3719a7f53dc1 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 21:25:03 -0800 Subject: [PATCH 12/37] MU counts for fields with limiting for small fields Only at higher zoom levels will counts for small fields show. --- code/map_data.js | 40 +++++++++++++++++++++++++++++----------- code/utils_misc.js | 5 +++++ main.js | 2 ++ style.css | 2 +- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 2731ff1a..529f9c70 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -522,17 +522,30 @@ window.renderField = function(ent) { if(Object.keys(fields).length >= MAX_DRAWN_FIELDS) return window.removeByGuid(ent[0]); - // assume that fields never change. If they do, they will have a - // different ID. - if(findEntityInLeaflet(fieldsLayer, fields, ent[0])) return; - - var team = getTeam(ent[2]); var reg = ent[2].capturedRegion; var latlngs = [ - [reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6], - [reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6], - [reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6] + new L.LatLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6), + new L.LatLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), + new L.LatLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) ]; + var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()) + + // Do nothing if zoom did not change. We need to recheck the field if the + // zoom level is different then when the field was rendered as it could + // now be appropriate or not to show an MU count + var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); + if(old) { + if(map.getZoom() == old.options.creationZoom) return; + var layerCount = 0; + old.eachLayer(function(item) { + layerCount++; + }); + if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 2) return; + if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 1) return; + removeByGuid(ent[0]); + } + + var team = getTeam(ent[2]); var poly = L.polygon(latlngs, { fillColor: COLORS[team], @@ -562,16 +575,21 @@ window.renderField = function(ent) { var fieldMu = L.marker(centroid, { icon: L.divIcon({ className: 'fieldmu', - iconSize: [100,12], - html: 'MU: ' + digits(ent[2].entityScore.entityScore)}), + iconSize: [70,12], + html: digits(ent[2].entityScore.entityScore)}), clickable: false }); // put both in one group, so they can be handled by the same logic. - var f = L.layerGroup([poly, fieldMu]); + if (areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO) { + var f = L.layerGroup([poly, fieldMu]); + } else { + var f = L.layerGroup([poly]); + } f.options = { vertices: reg, lastUpdate: ent[1], + creationZoom: map.getZoom(), guid: ent[0] }; diff --git a/code/utils_misc.js b/code/utils_misc.js index 1e5e0a87..270ce855 100644 --- a/code/utils_misc.js +++ b/code/utils_misc.js @@ -296,3 +296,8 @@ window.convertTextToTableMagic = function(text) { table += ''; return table; } + +// Given 3 sets of points in an array[3]{lat, lng} returns the area of the triangle +window.calcTriArea = function(p) { + return Math.abs((p[0].lat*(p[1].lng-p[2].lng)+p[1].lat*(p[2].lng-p[0].lng)+p[2].lat*(p[0].lng-p[1].lng))/2); +} diff --git a/main.js b/main.js index 7553fd48..04a62374 100644 --- a/main.js +++ b/main.js @@ -149,6 +149,8 @@ window.MAX_DRAWN_LINKS = 400; window.MAX_DRAWN_FIELDS = 200; // Minimum zoom level resonator will display window.RESONATOR_DISPLAY_ZOOM_LEVEL = 17; +// Minimum area to zoom ratio that field MU's will display +window.FIELD_MU_DISPLAY_AREA_ZOOM_RATIO = 0.001; window.COLOR_SELECTED_PORTAL = '#f00'; window.COLORS = ['#FFCE00', '#0088FF', '#03DC03']; // none, res, enl diff --git a/style.css b/style.css index 39d6cc49..7763bb22 100644 --- a/style.css +++ b/style.css @@ -94,12 +94,12 @@ a:hover { } /* field mu count */ - .fieldmu { color: #FFCE00; font-size:13px; font-family: "coda",arial,helvetica,sans-serif; /*override leaflet-container */ text-align: center; + text-shadow: 0 0 0.2em black, 0 0 0.2em black, 0 0 0.2em black; } From d4903c6ce7b12b04e574dc6ca1b471d9fc15fbf6 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 21:38:13 -0800 Subject: [PATCH 13/37] Code breaking bug fix --- code/map_data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/map_data.js b/code/map_data.js index 157ab1d6..2f055253 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -609,7 +609,7 @@ window.renderField = function(ent) { lastUpdate: ent[1], creationZoom: map.getZoom(), guid: ent[0], - data: ent[2]}); + data: ent[2] }; // However, LayerGroups (and FeatureGroups) don’t fire add/remove From 7c019e1eb8d35b1fe3b67b6529a03b9418c37b2d Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 21:51:12 -0800 Subject: [PATCH 14/37] Fix tabs and add comment about crazy equation --- code/map_data.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 2f055253..43f59b87 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -546,6 +546,8 @@ window.renderField = function(ent) { new L.LatLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), new L.LatLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) ]; + + // Curve fit equation to normalize zoom window area var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()) // Do nothing if zoom did not change. We need to recheck the field if the @@ -554,12 +556,12 @@ window.renderField = function(ent) { var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); if(old) { if(map.getZoom() == old.options.creationZoom) return; - var layerCount = 0; - old.eachLayer(function(item) { - layerCount++; - }); - if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 2) return; - if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 1) return; + var layerCount = 0; + old.eachLayer(function(item) { + layerCount++; + }); + if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 2) return; + if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 1) return; removeByGuid(ent[0]); } From 9889e0988f905769bfe9310dd618061b6f06204b Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 22:27:45 -0800 Subject: [PATCH 15/37] Fix to use identity operators --- code/map_data.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 43f59b87..b9c71724 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -555,13 +555,13 @@ window.renderField = function(ent) { // now be appropriate or not to show an MU count var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); if(old) { - if(map.getZoom() == old.options.creationZoom) return; + if(map.getZoom() === old.options.creationZoom) return; var layerCount = 0; old.eachLayer(function(item) { layerCount++; }); - if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 2) return; - if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 1) return; + if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount === 2) return; + if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount === 1) return; removeByGuid(ent[0]); } From f3606d6f0f5928de379e0d3089e05e4605702fb0 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 22:54:30 -0800 Subject: [PATCH 16/37] Fix neutral portals have broken random details --- code/portal_detail_display.js | 3 +-- code/portal_detail_display_tools.js | 2 +- code/portal_info.js | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/code/portal_detail_display.js b/code/portal_detail_display.js index 15dd160e..8e7a2a71 100644 --- a/code/portal_detail_display.js +++ b/code/portal_detail_display.js @@ -22,9 +22,8 @@ window.renderPortalDetails = function(guid) { var linksText = [linkExpl('links'), linkExpl(' ↳ ' + links.incoming+'  •  '+links.outgoing+' ↴')]; var player = d.captured && d.captured.capturingPlayerId - ? getPlayerName(d.captured.capturingPlayerId) + ? '' + getPlayerName(d.captured.capturingPlayerId) + '' : null; - player = ''+player+''; var playerText = player ? ['owner', player] : null; var time = d.captured diff --git a/code/portal_detail_display_tools.js b/code/portal_detail_display_tools.js index 9a50e1b7..1687f5d9 100644 --- a/code/portal_detail_display_tools.js +++ b/code/portal_detail_display_tools.js @@ -132,7 +132,7 @@ window.renderResonatorDetails = function(slot, level, nrg, dist, nick) { var meter = '' + fill + lbar + ''; } - nick = ''+nick+''; + nick = nick ? ''+nick+'' : null; return [meter, nick || '']; } diff --git a/code/portal_info.js b/code/portal_info.js index 2e2e2127..fdbc91c2 100644 --- a/code/portal_info.js +++ b/code/portal_info.js @@ -64,7 +64,7 @@ window.getAvgResoDist = function(d) { sum += parseInt(reso.distanceToPortal); resos++; }); - return sum/resos; + return resos ? sum/resos : 0; } window.getAttackApGain = function(d) { From e3b9a2b1ec799ce8622167168b79e707b9cefc01 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 3 Mar 2013 01:08:46 -0800 Subject: [PATCH 17/37] Fix up nits --- code/map_data.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index b9c71724..dd741ee7 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -199,7 +199,7 @@ window.cleanUp = function() { }); fieldsLayer.eachLayer(function(fieldgroup) { fieldgroup.eachLayer(function(item) { - if(!item.options.guid) return true; + if(!item.options.guid) return true; // Skip MU div container as this doesn't have the bounds we need if(b.intersects(item.getBounds())) return; cnt[2]++; fieldsLayer.removeLayer(fieldgroup); @@ -542,13 +542,13 @@ window.renderField = function(ent) { var reg = ent[2].capturedRegion; var latlngs = [ - new L.LatLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6), - new L.LatLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), - new L.LatLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) + L.latLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6), + L.latLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), + L.latLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) ]; // Curve fit equation to normalize zoom window area - var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()) + var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()); // Do nothing if zoom did not change. We need to recheck the field if the // zoom level is different then when the field was rendered as it could From 898f0c37ce20a424f707e98d7e7ac9fda6daa452 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 3 Mar 2013 01:21:50 -0800 Subject: [PATCH 18/37] One more nit --- code/map_data.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/map_data.js b/code/map_data.js index dd741ee7..1b885e7d 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -596,7 +596,8 @@ window.renderField = function(ent) { icon: L.divIcon({ className: 'fieldmu', iconSize: [70,12], - html: digits(ent[2].entityScore.entityScore)}), + html: digits(ent[2].entityScore.entityScore) + }), clickable: false }); From 5f94d56578949d70a016cb6131ef98bd096ef8ca Mon Sep 17 00:00:00 2001 From: Xelio Date: Sun, 3 Mar 2013 22:42:51 +0800 Subject: [PATCH 19/37] Add guid to window.PLAYER and add constant MAX_RESO_PER_PLAYER --- code/boot.js | 1 + code/player_names.js | 11 +++++++++++ main.js | 1 + 3 files changed, 13 insertions(+) diff --git a/code/boot.js b/code/boot.js index 7e5882a2..6c97cb55 100644 --- a/code/boot.js +++ b/code/boot.js @@ -159,6 +159,7 @@ window.setupMap = function() { // included as inline script in the original site, the data is static // and cannot be updated. window.setupPlayerStat = function() { + PLAYER.guid = playerNameToGuid(PLAYER.nickname); var level; var ap = parseInt(PLAYER.ap); for(level = 0; level < MIN_AP_FOR_LEVEL.length; level++) { diff --git a/code/player_names.js b/code/player_names.js index 85362f2c..0d2557d5 100644 --- a/code/player_names.js +++ b/code/player_names.js @@ -17,6 +17,17 @@ window.getPlayerName = function(guid) { return '{'+guid.slice(0, 12)+'}'; } +window.playerNameToGuid = function(playerName){ + var guid = null; + $.each(Object.keys(localStorage), function(ind,key) { + if(playerName === localStorage[key]) { + guid = key; + return false; + } + }); + return guid; +} + // resolves all player GUIDs that have been added to the list. Reruns // renderPortalDetails when finished, so that then-unresolved names // get replaced by their correct versions. diff --git a/main.js b/main.js index 7553fd48..d4328181 100644 --- a/main.js +++ b/main.js @@ -189,6 +189,7 @@ window.CAPTURE_PORTAL = 500; //AP for capturing a portal window.DEPLOY_RESONATOR = 125; //AP for deploying a resonator window.COMPLETION_BONUS = 250; //AP for deploying all resonators on portal window.MAX_PORTAL_LEVEL = 8; +window.MAX_RESO_PER_PLAYER = [0, 8, 4, 4, 4, 2, 2, 1, 1]; // OTHER MORE-OR-LESS CONSTANTS ////////////////////////////////////// window.TEAM_NONE = 0; From 5e8cab6c885dc9d8d6284eb88ff46a7abf2de67e Mon Sep 17 00:00:00 2001 From: Xelio Date: Sun, 3 Mar 2013 23:59:44 +0800 Subject: [PATCH 20/37] Store player level at setupPlayerStat --- code/boot.js | 1 + 1 file changed, 1 insertion(+) diff --git a/code/boot.js b/code/boot.js index 6c97cb55..2204acd1 100644 --- a/code/boot.js +++ b/code/boot.js @@ -165,6 +165,7 @@ window.setupPlayerStat = function() { for(level = 0; level < MIN_AP_FOR_LEVEL.length; level++) { if(ap < MIN_AP_FOR_LEVEL[level]) break; } + PLAYER.level = level; var thisLvlAp = MIN_AP_FOR_LEVEL[level-1]; var nextLvlAp = MIN_AP_FOR_LEVEL[level] || ap; From 3263664e489d8b2cacca8eaef318748d6c67a27a Mon Sep 17 00:00:00 2001 From: Xelio Date: Mon, 4 Mar 2013 00:33:52 +0800 Subject: [PATCH 21/37] Add window.UPGRADE_ANOTHERS_RESONATOR --- main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/main.js b/main.js index d4328181..ff11efb8 100644 --- a/main.js +++ b/main.js @@ -188,6 +188,7 @@ window.DESTROY_FIELD = 750; //AP for destroying field window.CAPTURE_PORTAL = 500; //AP for capturing a portal window.DEPLOY_RESONATOR = 125; //AP for deploying a resonator window.COMPLETION_BONUS = 250; //AP for deploying all resonators on portal +window.UPGRADE_ANOTHERS_RESONATOR = 65; //AP for upgrading another's resonator window.MAX_PORTAL_LEVEL = 8; window.MAX_RESO_PER_PLAYER = [0, 8, 4, 4, 4, 2, 2, 1, 1]; From 01f7b7099d78401fd064b7bc7940cfba45db3f12 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 3 Mar 2013 19:17:17 -0800 Subject: [PATCH 22/37] Use LineUtil.simplify, rearange some code --- code/map_data.js | 70 +++++++++++++++++++++++++----------------------- main.js | 2 ++ 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 1b885e7d..6dc7f0c9 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -539,33 +539,18 @@ window.renderLink = function(ent) { window.renderField = function(ent) { if(Object.keys(fields).length >= MAX_DRAWN_FIELDS) return window.removeByGuid(ent[0]); + + var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); + // If this already exists and the zoom level has not changed, we don't need to do anything + if(old && map.getZoom() === old.options.creationZoom) return; + var team = getTeam(ent[2]); var reg = ent[2].capturedRegion; var latlngs = [ L.latLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6), L.latLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), L.latLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) ]; - - // Curve fit equation to normalize zoom window area - var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()); - - // Do nothing if zoom did not change. We need to recheck the field if the - // zoom level is different then when the field was rendered as it could - // now be appropriate or not to show an MU count - var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); - if(old) { - if(map.getZoom() === old.options.creationZoom) return; - var layerCount = 0; - old.eachLayer(function(item) { - layerCount++; - }); - if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount === 2) return; - if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount === 1) return; - removeByGuid(ent[0]); - } - - var team = getTeam(ent[2]); var poly = L.polygon(latlngs, { fillColor: COLORS[team], @@ -587,22 +572,41 @@ window.renderField = function(ent) { if(!getPaddedBounds().intersects(poly.getBounds())) return; - var centroid = [ - (latlngs[0].lat + latlngs[1].lat + latlngs[2].lat)/3, - (latlngs[0].lng + latlngs[1].lng + latlngs[2].lng)/3 - ]; - - var fieldMu = L.marker(centroid, { - icon: L.divIcon({ - className: 'fieldmu', - iconSize: [70,12], - html: digits(ent[2].entityScore.entityScore) - }), - clickable: false + // Curve fit equation to normalize zoom window area + var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()); + var countForMUDisplay = L.LineUtil.simplify(poly._originalPoints, FIELD_MU_DISPLAY_POINT_TOLERANCE).length + + // Do nothing if zoom did not change. We need to recheck the field if the + // zoom level is different then when the field was rendered as it could + // now be appropriate or not to show an MU count + if(old) { + var layerCount = 0; + old.eachLayer(function(item) { + layerCount++; }); + // Don't do anything since we already have an MU display and we still want to + if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && countForMUDisplay > 2 && layerCount === 2) return; + // Don't do anything since we don't have an MU display and don't want to + if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && countForMUDisplay <= 2 && layerCount === 1) return; + removeByGuid(ent[0]); + } // put both in one group, so they can be handled by the same logic. - if (areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO) { + if (areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && countForMUDisplay > 2) { + // centroid of field for placing MU count at + var centroid = [ + (latlngs[0].lat + latlngs[1].lat + latlngs[2].lat)/3, + (latlngs[0].lng + latlngs[1].lng + latlngs[2].lng)/3 + ]; + + var fieldMu = L.marker(centroid, { + icon: L.divIcon({ + className: 'fieldmu', + iconSize: [70,12], + html: digits(ent[2].entityScore.entityScore) + }), + clickable: false + }); var f = L.layerGroup([poly, fieldMu]); } else { var f = L.layerGroup([poly]); diff --git a/main.js b/main.js index 04a62374..972b4729 100644 --- a/main.js +++ b/main.js @@ -151,6 +151,8 @@ window.MAX_DRAWN_FIELDS = 200; window.RESONATOR_DISPLAY_ZOOM_LEVEL = 17; // Minimum area to zoom ratio that field MU's will display window.FIELD_MU_DISPLAY_AREA_ZOOM_RATIO = 0.001; +// Point tolerance for displaying MU's +window.FIELD_MU_DISPLAY_POINT_TOLERANCE = 60 window.COLOR_SELECTED_PORTAL = '#f00'; window.COLORS = ['#FFCE00', '#0088FF', '#03DC03']; // none, res, enl From 0520d8bb9a3bdf911d6db10a4bf75dc768418a16 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 22:54:30 -0800 Subject: [PATCH 23/37] Fix neutral portals have broken random details --- code/portal_detail_display.js | 3 +-- code/portal_detail_display_tools.js | 2 +- code/portal_info.js | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/code/portal_detail_display.js b/code/portal_detail_display.js index 15dd160e..8e7a2a71 100644 --- a/code/portal_detail_display.js +++ b/code/portal_detail_display.js @@ -22,9 +22,8 @@ window.renderPortalDetails = function(guid) { var linksText = [linkExpl('links'), linkExpl(' ↳ ' + links.incoming+'  •  '+links.outgoing+' ↴')]; var player = d.captured && d.captured.capturingPlayerId - ? getPlayerName(d.captured.capturingPlayerId) + ? '' + getPlayerName(d.captured.capturingPlayerId) + '' : null; - player = ''+player+''; var playerText = player ? ['owner', player] : null; var time = d.captured diff --git a/code/portal_detail_display_tools.js b/code/portal_detail_display_tools.js index 9a50e1b7..1687f5d9 100644 --- a/code/portal_detail_display_tools.js +++ b/code/portal_detail_display_tools.js @@ -132,7 +132,7 @@ window.renderResonatorDetails = function(slot, level, nrg, dist, nick) { var meter = '' + fill + lbar + ''; } - nick = ''+nick+''; + nick = nick ? ''+nick+'' : null; return [meter, nick || '']; } diff --git a/code/portal_info.js b/code/portal_info.js index 2e2e2127..fdbc91c2 100644 --- a/code/portal_info.js +++ b/code/portal_info.js @@ -64,7 +64,7 @@ window.getAvgResoDist = function(d) { sum += parseInt(reso.distanceToPortal); resos++; }); - return sum/resos; + return resos ? sum/resos : 0; } window.getAttackApGain = function(d) { From e59fdc8296fe2b0cecf8cb88a28e8227b568c17b Mon Sep 17 00:00:00 2001 From: Xelio Date: Sun, 3 Mar 2013 22:42:51 +0800 Subject: [PATCH 24/37] Add guid to window.PLAYER and add constant MAX_RESO_PER_PLAYER --- code/boot.js | 1 + code/player_names.js | 11 +++++++++++ main.js | 1 + 3 files changed, 13 insertions(+) diff --git a/code/boot.js b/code/boot.js index 7e5882a2..6c97cb55 100644 --- a/code/boot.js +++ b/code/boot.js @@ -159,6 +159,7 @@ window.setupMap = function() { // included as inline script in the original site, the data is static // and cannot be updated. window.setupPlayerStat = function() { + PLAYER.guid = playerNameToGuid(PLAYER.nickname); var level; var ap = parseInt(PLAYER.ap); for(level = 0; level < MIN_AP_FOR_LEVEL.length; level++) { diff --git a/code/player_names.js b/code/player_names.js index 85362f2c..0d2557d5 100644 --- a/code/player_names.js +++ b/code/player_names.js @@ -17,6 +17,17 @@ window.getPlayerName = function(guid) { return '{'+guid.slice(0, 12)+'}'; } +window.playerNameToGuid = function(playerName){ + var guid = null; + $.each(Object.keys(localStorage), function(ind,key) { + if(playerName === localStorage[key]) { + guid = key; + return false; + } + }); + return guid; +} + // resolves all player GUIDs that have been added to the list. Reruns // renderPortalDetails when finished, so that then-unresolved names // get replaced by their correct versions. diff --git a/main.js b/main.js index 7553fd48..d4328181 100644 --- a/main.js +++ b/main.js @@ -189,6 +189,7 @@ window.CAPTURE_PORTAL = 500; //AP for capturing a portal window.DEPLOY_RESONATOR = 125; //AP for deploying a resonator window.COMPLETION_BONUS = 250; //AP for deploying all resonators on portal window.MAX_PORTAL_LEVEL = 8; +window.MAX_RESO_PER_PLAYER = [0, 8, 4, 4, 4, 2, 2, 1, 1]; // OTHER MORE-OR-LESS CONSTANTS ////////////////////////////////////// window.TEAM_NONE = 0; From c6bc9c2e03f83537a543d5e80d61a60266b83e46 Mon Sep 17 00:00:00 2001 From: Xelio Date: Sun, 3 Mar 2013 23:59:44 +0800 Subject: [PATCH 25/37] Store player level at setupPlayerStat --- code/boot.js | 1 + 1 file changed, 1 insertion(+) diff --git a/code/boot.js b/code/boot.js index 6c97cb55..2204acd1 100644 --- a/code/boot.js +++ b/code/boot.js @@ -165,6 +165,7 @@ window.setupPlayerStat = function() { for(level = 0; level < MIN_AP_FOR_LEVEL.length; level++) { if(ap < MIN_AP_FOR_LEVEL[level]) break; } + PLAYER.level = level; var thisLvlAp = MIN_AP_FOR_LEVEL[level-1]; var nextLvlAp = MIN_AP_FOR_LEVEL[level] || ap; From ecbe0850cea6f34f324ce219ae3bd58431d3d93d Mon Sep 17 00:00:00 2001 From: Xelio Date: Mon, 4 Mar 2013 00:33:52 +0800 Subject: [PATCH 26/37] Add window.UPGRADE_ANOTHERS_RESONATOR --- main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/main.js b/main.js index d4328181..ff11efb8 100644 --- a/main.js +++ b/main.js @@ -188,6 +188,7 @@ window.DESTROY_FIELD = 750; //AP for destroying field window.CAPTURE_PORTAL = 500; //AP for capturing a portal window.DEPLOY_RESONATOR = 125; //AP for deploying a resonator window.COMPLETION_BONUS = 250; //AP for deploying all resonators on portal +window.UPGRADE_ANOTHERS_RESONATOR = 65; //AP for upgrading another's resonator window.MAX_PORTAL_LEVEL = 8; window.MAX_RESO_PER_PLAYER = [0, 8, 4, 4, 4, 2, 2, 1, 1]; From 68a89da6a0d8c7abd6559b876d7204b9ed8222ba Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 3 Mar 2013 19:42:23 -0800 Subject: [PATCH 27/37] Add Fragger to contribs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0aa40d4b..af865dc5 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ First of all, it’s very nice you want to help. There are several equally impor [boombuler](https://github.com/boombuler), [cmrn](https://github.com/cmrn), [epf](https://github.com/epf), +[Fragger](https://github.com/Fragger), [integ3r](https://github.com/integ3r), [j16sdiz](https://github.com/j16sdiz), [JasonMillward](https://github.com/JasonMillward), From 45bed379ec6f27c3337aec89ed1356bae4b0b3bd Mon Sep 17 00:00:00 2001 From: Stefan Breunig Date: Mon, 4 Mar 2013 09:46:30 +0100 Subject: [PATCH 28/37] implement scale bar plugin (fix #291) --- plugins/README.md | 2 ++ plugins/scale-bar.user.js | 48 +++++++++++++++++++++++++++++++ screenshots/plugin_scale_bar.png | Bin 0 -> 81322 bytes 3 files changed, 50 insertions(+) create mode 100644 plugins/scale-bar.user.js create mode 100644 screenshots/plugin_scale_bar.png diff --git a/plugins/README.md b/plugins/README.md index c90ab10e..81b6b942 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -18,6 +18,8 @@ Available Plugins - [**Render Limit Increase**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/render-limit-increase.user.js) increases render limits. Good for high density areas (e.g. London, UK) and faster PCs. - [**Resonator Display Zoom Level Decrease**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/resonator-display-zoom-level-decrease.user.js) Resonator start displaying earlier. - [**Resonator Energy in Portal Detail**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/reso-energy-pct-in-portal-detail.user.js) Resonator energy in percent is displayed in the portal detals. +- [**Scale Bar**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scale-bar.user.js) Shows a scale bar in the top left corner. [View screenshot](http://breunigs.github.com/ingress-intel-total-conversion/scre +enshots/plugin_scale_bar.png) - [**Show Portal Address**](https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/show-address.user.js) Shows portal address in the side panel. ### available only with the development version diff --git a/plugins/scale-bar.user.js b/plugins/scale-bar.user.js new file mode 100644 index 00000000..1b1e44ac --- /dev/null +++ b/plugins/scale-bar.user.js @@ -0,0 +1,48 @@ +// ==UserScript== +// @id iitc-plugin-scale-bar@breunigs +// @name iitc: scale bar +// @version 0.1 +// @namespace https://github.com/breunigs/ingress-intel-total-conversion +// @updateURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scale-bar.user.js +// @downloadURL https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scale-bar.user.js +// @description shows scale bar on the map +// @include https://www.ingress.com/intel* +// @match https://www.ingress.com/intel* +// ==/UserScript== + +function wrapper() { +// ensure plugin framework is there, even if iitc is not yet loaded +if(typeof window.plugin !== 'function') window.plugin = function() {}; + + +// PLUGIN START //////////////////////////////////////////////////////// + + +// use own namespace for plugin +window.plugin.scaleBar = function() {}; + +window.plugin.scaleBar.setup = function() { + $('head').append(''); + // Before you ask: yes, I explicitely turned off imperial units. Imperial units + // are worse than Internet Explorer 6 whirring fans combined. Upgrade to the metric + // system already. + window.map.addControl(new L.Control.Scale({position: 'topleft', imperial: false})); +}; + +var setup = window.plugin.scaleBar.setup; + +// PLUGIN END ////////////////////////////////////////////////////////// + +if(window.iitcLoaded && typeof setup === 'function') { + setup(); +} else { + if(window.bootPlugins) + window.bootPlugins.push(setup); + else + window.bootPlugins = [setup]; +} +} // wrapper end +// inject code into site context +var script = document.createElement('script'); +script.appendChild(document.createTextNode('('+ wrapper +')();')); +(document.body || document.head || document.documentElement).appendChild(script); diff --git a/screenshots/plugin_scale_bar.png b/screenshots/plugin_scale_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..d83762de477e279a5e7dc007f5154487b8461846 GIT binary patch literal 81322 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 Q81PR`SzGC?;{AyK10w`HcK`qY literal 0 HcmV?d00001 From f50a7eb63cc2843e6f594038998bfe7736d16fcf Mon Sep 17 00:00:00 2001 From: Florian Sundermann Date: Mon, 4 Mar 2013 12:32:22 +0100 Subject: [PATCH 29/37] new style for alert windows --- style.css | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/style.css b/style.css index f25501f9..bfed9b72 100644 --- a/style.css +++ b/style.css @@ -679,15 +679,14 @@ aside { max-width: 300px; position: absolute; z-index: 9999; - background-color: #fff; - border: 1px solid #ccc; - color: #222; - font: 13px/15px "Helvetica Neue", Arial, Helvetica, sans-serif; + background-color: rgba(8, 48, 78, 0.9); + border: 1px solid #20A8B1; + color: #eee; + font: 13px/15px "coda","Helvetica Neue", Arial, Helvetica, sans-serif; padding: 2px 4px; } .ui-dialog { - border: 1px solid #0F0F0F; padding: 0; border-radius: 2px; } @@ -720,9 +719,8 @@ aside { } .ui-dialog-buttonpane { - background: #F2F2F2; padding: 12px; - border-top: 1px solid #E6E6E6; + border-top: 1px solid #20A8B1; } .ui-dialog-buttonset { @@ -732,6 +730,13 @@ aside { .ui-dialog-buttonset button { padding: 2px; min-width: 80px; + color: #FFCE00; + border: 1px solid #FFCE00; + background-color: rgba(8, 48, 78, 0.9); +} + +.ui-dialog-buttonset button:hover { + text-decoration: underline; } td { From eb3ec79852a1591f54451ed331cb531838eee108 Mon Sep 17 00:00:00 2001 From: Xelio Date: Tue, 5 Mar 2013 03:17:46 +0800 Subject: [PATCH 30/37] Add hook: requestFinished Called after each request finished. Argument is {success: boolean} indicated the request success or fail. --- code/hooks.js | 5 +++-- code/map_data.js | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/code/hooks.js b/code/hooks.js index fbf5c602..c3e0aa25 100644 --- a/code/hooks.js +++ b/code/hooks.js @@ -46,14 +46,15 @@ // checkRenderLimit: callback is passed the argument of // {reached : false} to indicate that the renderlimit is reached // set reached to true. - +// requestFinished: called after each request finished. Argument is +// {success: boolean} indicated the request success or fail. window._hooks = {} window.VALID_HOOKS = ['portalAdded', 'portalDetailsUpdated', 'publicChatDataAvailable', 'portalDataLoaded', 'beforePortalReRender', - 'checkRenderLimit']; + 'checkRenderLimit', 'requestFinished']; window.runHooks = function(event, data) { if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event); diff --git a/code/map_data.js b/code/map_data.js index 6dc7f0c9..c8ccf116 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -59,6 +59,7 @@ window.handleFailedRequest = function() { var leftOverPortals = portalRenderLimit.mergeLowLevelPortals(null); handlePortalsRender(leftOverPortals); } + runHooks('requestFinished', {success: false}); } // works on map data response and ensures entities are drawn/updated. @@ -139,6 +140,7 @@ window.handleDataResponse = function(data, textStatus, jqXHR) { resolvePlayerNames(); renderUpdateStatus(); + runHooks('requestFinished', {success: true}); } window.handlePortalsRender = function(portals) { From 492f0846f846ca9598ec37d68146e88cf2cf0ed0 Mon Sep 17 00:00:00 2001 From: boombuler Date: Mon, 4 Mar 2013 21:02:25 +0100 Subject: [PATCH 31/37] Fixed some style issues --- plugins/player-tracker.user.js | 4 ++-- style.css | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/player-tracker.user.js b/plugins/player-tracker.user.js index f52f4347..fe9c66a8 100644 --- a/plugins/player-tracker.user.js +++ b/plugins/player-tracker.user.js @@ -204,9 +204,9 @@ window.plugin.playerTracker.drawData = function() { var evtsLength = playerData.events.length; var last = playerData.events[evtsLength-1]; var ago = plugin.playerTracker.ago; - var color = playerData.team === 'ALIENS' ? '#029C02' : '#00789C'; + var cssClass = playerData.team === 'ALIENS' ? 'enl' : 'res'; var title = - '' + playerData.nick + '\n' + '' + playerData.nick + '\n' + ago(last.time, now) + ' minutes ago\n' + last.name; // show previous data in tooltip diff --git a/style.css b/style.css index bfed9b72..7b79982e 100644 --- a/style.css +++ b/style.css @@ -682,10 +682,14 @@ aside { background-color: rgba(8, 48, 78, 0.9); border: 1px solid #20A8B1; color: #eee; - font: 13px/15px "coda","Helvetica Neue", Arial, Helvetica, sans-serif; + font: 13px/15px "Helvetica Neue", Arial, Helvetica, sans-serif; padding: 2px 4px; } +.ui-tooltip, .ui-dialog a { + color: #FFCE00; +} + .ui-dialog { padding: 0; border-radius: 2px; @@ -714,10 +718,6 @@ aside { max-width: 700px !important; } -.ui-dialog a { - color: #0000ca; -} - .ui-dialog-buttonpane { padding: 12px; border-top: 1px solid #20A8B1; From 3c1c596a6a2471573e3c8b2e6fa2b6e488692feb Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Mon, 4 Mar 2013 15:55:01 -0600 Subject: [PATCH 32/37] * Add detailed error messages for redemption errors (including rate-limiting, which happens sometimes). * Reverse XMPs and resonators in redemption display --- code/redeeming.js | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/code/redeeming.js b/code/redeeming.js index 51a126dc..12bc5e32 100644 --- a/code/redeeming.js +++ b/code/redeeming.js @@ -12,12 +12,12 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) { } else if (data.error === 'INVALID_PASSCODE') { error = 'This passcode is invalid.'; } else { - error = 'The passcode cannot be redeemed.'; + error = 'There was a problem redeeming the passcode. Try again?'; } - alert("Error: " + data.error + "\n" + error); + alert('' + data.error + "\n" + error); } else if (data.result) { - var res_level = 0, res_count = 0; var xmp_level = 0, xmp_count = 0; + var res_level = 0, res_count = 0; var shield_rarity = '', shield_count = 0; // This assumes that each passcode gives only one type of resonator/XMP/shield. @@ -30,17 +30,17 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) { shield_count++; } } else if (acquired.resourceWithLevels) { - if (acquired.resourceWithLevels.resourceType === 'EMITTER_A') { - res_level = acquired.resourceWithLevels.level; - res_count++; - } else if (acquired.resourceWithLevels.resourceType === 'EMP_BURSTER') { + if (acquired.resourceWithLevels.resourceType === 'EMP_BURSTER') { xmp_level = acquired.resourceWithLevels.level; xmp_count++; + } else if (acquired.resourceWithLevels.resourceType === 'EMITTER_A') { + res_level = acquired.resourceWithLevels.level; + res_count++; } } } - alert("Passcode redeemed!\n" + [data.result.apAward + 'AP', data.result.xmAward + 'XM', res_count + 'xL' + res_level + ' RES', xmp_count + 'xL' + xmp_level + ' XMP', shield_count + 'x' + shield_rarity + ' SHIELD'].join('/')); + alert("Passcode accepted!\n" + [data.result.apAward + 'AP', data.result.xmAward + 'XM', xmp_count + 'xL' + xmp_level + ' XMP', res_count + 'xL' + res_level + ' RES', shield_count + 'x' + shield_rarity + ' SH'].join('/')); } } @@ -49,6 +49,19 @@ window.setupRedeem = function() { if((e.keyCode ? e.keyCode : e.which) != 13) return; var data = {passcode: $(this).val()}; window.postAjax('redeemReward', data, window.handleRedeemResponse, - function() { alert('The HTTP request failed. Either your code is invalid or their servers are down. No way to tell.'); }); + function(response) { + var extra = ''; + if (response && response.status) { + if (response.status === 429) { + extra = "You have been rate-limited by the server. Wait a bit and try again."; + } else { + extra = "The server indicated an error."; + } + extra += "\n" + 'Response: HTTP ' + jq.status + "."; + } else { + extra = "No status code was returned."; + } + alert('The HTTP request failed. ' + extra); + }); }); } From 4024c67f3aa290d697eb44a7ac0ff96fb192d577 Mon Sep 17 00:00:00 2001 From: Xelio Date: Tue, 5 Mar 2013 16:23:38 +0800 Subject: [PATCH 33/37] Make style of buttons in dialog consistant. --- style.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/style.css b/style.css index 7b79982e..31270562 100644 --- a/style.css +++ b/style.css @@ -727,7 +727,8 @@ aside { text-align: right; } -.ui-dialog-buttonset button { +.ui-dialog-buttonset button, +.ui-dialog-content button { padding: 2px; min-width: 80px; color: #FFCE00; From dbda13112ebb0defe959683afbca965df7842614 Mon Sep 17 00:00:00 2001 From: Xelio Date: Tue, 5 Mar 2013 23:10:49 +0800 Subject: [PATCH 34/37] Bug fix in "isSameResonator" It was throwing error when only one of the resonator is null. --- code/map_data.js | 1 + 1 file changed, 1 insertion(+) diff --git a/code/map_data.js b/code/map_data.js index c8ccf116..3da36190 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -453,6 +453,7 @@ window.isResonatorsShow = function() { window.isSameResonator = function(oldRes, newRes) { if(!oldRes && !newRes) return true; + if(!oldRes || !newRes) return false; if(typeof oldRes !== typeof newRes) return false; if(oldRes.level !== newRes.level) return false; if(oldRes.energyTotal !== newRes.energyTotal) return false; From a4489125000134597172b2e5733268653fc5096b Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Tue, 5 Mar 2013 16:09:43 -0600 Subject: [PATCH 35/37] Fix display of HTTP error messages for code redemption --- code/redeeming.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/redeeming.js b/code/redeeming.js index 12bc5e32..0a0575b0 100644 --- a/code/redeeming.js +++ b/code/redeeming.js @@ -57,7 +57,7 @@ window.setupRedeem = function() { } else { extra = "The server indicated an error."; } - extra += "\n" + 'Response: HTTP ' + jq.status + "."; + extra += "\n" + 'Response: HTTP ' + response.status + "."; } else { extra = "No status code was returned."; } From 0d5275c385129c28a6524c452d7265f089875263 Mon Sep 17 00:00:00 2001 From: Stefan Breunig Date: Tue, 5 Mar 2013 23:23:26 +0100 Subject: [PATCH 36/37] typo that prevented smartphone style from being loaded --- main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.js b/main.js index 18c5c834..cfe5a743 100644 --- a/main.js +++ b/main.js @@ -67,7 +67,7 @@ document.getElementsByTagName('head')[0].innerHTML = '' + '' // this navigator check is also used in code/smartphone.js + (navigator.userAgent.match(/Android.*Mobile/) - ? + '' + ? '' : '') + ''; From b30ac36ffa026fc0bebe33745c38d1c21a52ac0f Mon Sep 17 00:00:00 2001 From: Stefan Breunig Date: Wed, 6 Mar 2013 00:02:28 +0100 Subject: [PATCH 37/37] fix style nits --- code/redeeming.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/redeeming.js b/code/redeeming.js index 0a0575b0..0792f17d 100644 --- a/code/redeeming.js +++ b/code/redeeming.js @@ -14,7 +14,7 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) { } else { error = 'There was a problem redeeming the passcode. Try again?'; } - alert('' + data.error + "\n" + error); + alert('' + data.error + '\n' + error); } else if (data.result) { var xmp_level = 0, xmp_count = 0; var res_level = 0, res_count = 0; @@ -40,7 +40,7 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) { } } - alert("Passcode accepted!\n" + [data.result.apAward + 'AP', data.result.xmAward + 'XM', xmp_count + 'xL' + xmp_level + ' XMP', res_count + 'xL' + res_level + ' RES', shield_count + 'x' + shield_rarity + ' SH'].join('/')); + alert('Passcode accepted!\n' + [data.result.apAward + 'AP', data.result.xmAward + 'XM', xmp_count + 'xL' + xmp_level + ' XMP', res_count + 'xL' + res_level + ' RES', shield_count + 'x' + shield_rarity + ' SH'].join('/')); } } @@ -53,13 +53,13 @@ window.setupRedeem = function() { var extra = ''; if (response && response.status) { if (response.status === 429) { - extra = "You have been rate-limited by the server. Wait a bit and try again."; + extra = 'You have been rate-limited by the server. Wait a bit and try again.'; } else { - extra = "The server indicated an error."; + extra = 'The server indicated an error.'; } - extra += "\n" + 'Response: HTTP ' + response.status + "."; + extra += '\nResponse: HTTP ' + response.status + '.'; } else { - extra = "No status code was returned."; + extra = 'No status code was returned.'; } alert('The HTTP request failed. ' + extra); });