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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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