work in progress - first attempt to use new rendering code
lots of things currently broken though...
This commit is contained in:
parent
fa11087621
commit
07c28538fd
17
code/boot.js
17
code/boot.js
@ -183,22 +183,7 @@ window.setupMap = function() {
|
|||||||
map.attributionControl.setPrefix('');
|
map.attributionControl.setPrefix('');
|
||||||
// listen for changes and store them in cookies
|
// listen for changes and store them in cookies
|
||||||
map.on('moveend', window.storeMapPosition);
|
map.on('moveend', window.storeMapPosition);
|
||||||
map.on('zoomend', function() {
|
map.on('zoomend', window.storeMapPosition);
|
||||||
window.storeMapPosition();
|
|
||||||
|
|
||||||
// remove all resonators if zoom out to < RESONATOR_DISPLAY_ZOOM_LEVEL
|
|
||||||
if(isResonatorsShow()) return;
|
|
||||||
for(var i = 1; i < portalsLayers.length; i++) {
|
|
||||||
portalsLayers[i].eachLayer(function(item) {
|
|
||||||
var itemGuid = item.options.guid;
|
|
||||||
// check if 'item' is a resonator
|
|
||||||
if(getTypeByGuid(itemGuid) != TYPE_RESONATOR) return true;
|
|
||||||
portalsLayers[i].removeLayer(item);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Remove all resonators');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// map update status handling & update map hooks
|
// map update status handling & update map hooks
|
||||||
|
687
code/map_data.js
687
code/map_data.js
@ -38,7 +38,7 @@ window.debugSetTileColour = function(qk,bordercol,fillcol) {
|
|||||||
|
|
||||||
// cache for data tiles. indexed by the query key (qk)
|
// cache for data tiles. indexed by the query key (qk)
|
||||||
window.cache = undefined;
|
window.cache = undefined;
|
||||||
|
window.render = undefined;
|
||||||
|
|
||||||
|
|
||||||
// due to the cache (and race conditions in the server) - and now also oddities in the returned data
|
// due to the cache (and race conditions in the server) - and now also oddities in the returned data
|
||||||
@ -49,11 +49,11 @@ window._deletedEntityGuid = {}
|
|||||||
// works, refer to the description in “MAP DATA REQUEST CALCULATORS”
|
// works, refer to the description in “MAP DATA REQUEST CALCULATORS”
|
||||||
window.requestData = function() {
|
window.requestData = function() {
|
||||||
if (window.cache === undefined) window.cache = new DataCache();
|
if (window.cache === undefined) window.cache = new DataCache();
|
||||||
|
if (window.render === undefined) window.render = new Render();
|
||||||
|
|
||||||
|
|
||||||
console.log('refreshing data');
|
console.log('refreshing data');
|
||||||
requests.abort();
|
requests.abort();
|
||||||
cleanUp();
|
|
||||||
window.statusTotalMapTiles = 0;
|
window.statusTotalMapTiles = 0;
|
||||||
window.statusCachedMapTiles = 0;
|
window.statusCachedMapTiles = 0;
|
||||||
window.statusSuccessMapTiles = 0;
|
window.statusSuccessMapTiles = 0;
|
||||||
@ -67,6 +67,10 @@ window.requestData = function() {
|
|||||||
|
|
||||||
cache.expire();
|
cache.expire();
|
||||||
|
|
||||||
|
|
||||||
|
render.startRenderPass();
|
||||||
|
|
||||||
|
|
||||||
//a limit on the number of map tiles to be pulled in a single request
|
//a limit on the number of map tiles to be pulled in a single request
|
||||||
var MAX_TILES_PER_BUCKET = 18;
|
var MAX_TILES_PER_BUCKET = 18;
|
||||||
// the number of separate buckets. more can be created if the size exceeds MAX_TILES_PER_BUCKET
|
// the number of separate buckets. more can be created if the size exceeds MAX_TILES_PER_BUCKET
|
||||||
@ -87,7 +91,6 @@ window.requestData = function() {
|
|||||||
tiles = {};
|
tiles = {};
|
||||||
fullBucketCount = 0;
|
fullBucketCount = 0;
|
||||||
|
|
||||||
var cachedData = { result: { map: {} } };
|
|
||||||
var requestTileCount = 0;
|
var requestTileCount = 0;
|
||||||
|
|
||||||
// y goes from left to right
|
// y goes from left to right
|
||||||
@ -105,9 +108,10 @@ window.requestData = function() {
|
|||||||
|
|
||||||
// TODO?: if the selected portal is in this tile, always fetch the data
|
// TODO?: if the selected portal is in this tile, always fetch the data
|
||||||
if (cache.isFresh(tile_id)) {
|
if (cache.isFresh(tile_id)) {
|
||||||
// TODO: don't add tiles from the cache when 1. they were fully visible before, and 2. the zoom level is unchanged
|
var tiledata = cache.get(tile_id);
|
||||||
// TODO?: if a closer zoom level has all four tiles in the cache, use them instead?
|
|
||||||
cachedData.result.map[tile_id] = cache.get(tile_id);
|
render.processTileData (tiledata);
|
||||||
|
|
||||||
debugSetTileColour(tile_id,'#0f0','#ff0');
|
debugSetTileColour(tile_id,'#0f0','#ff0');
|
||||||
window.statusCachedMapTiles++;
|
window.statusCachedMapTiles++;
|
||||||
} else {
|
} else {
|
||||||
@ -146,6 +150,7 @@ window.requestData = function() {
|
|||||||
// Reset previous result of Portal Render Limit handler
|
// Reset previous result of Portal Render Limit handler
|
||||||
portalRenderLimit.init();
|
portalRenderLimit.init();
|
||||||
|
|
||||||
|
|
||||||
// send ajax requests
|
// send ajax requests
|
||||||
console.log('requesting '+requestTileCount+' tiles in '+Object.keys(tiles).length+' requests');
|
console.log('requesting '+requestTileCount+' tiles in '+Object.keys(tiles).length+' requests');
|
||||||
$.each(tiles, function(ind, tls) {
|
$.each(tiles, function(ind, tls) {
|
||||||
@ -167,12 +172,11 @@ window.requestData = function() {
|
|||||||
window.requests.add(window.postAjax('getThinnedEntitiesV4', data, function(data, textStatus, jqXHR) { window.handleDataResponse(data,false,tile_ids); }, function() { window.handleFailedRequest(tile_ids); }));
|
window.requests.add(window.postAjax('getThinnedEntitiesV4', data, function(data, textStatus, jqXHR) { window.handleDataResponse(data,false,tile_ids); }, function() { window.handleFailedRequest(tile_ids); }));
|
||||||
});
|
});
|
||||||
|
|
||||||
// process the requests from the cache
|
if(tiles.length == 0) {
|
||||||
console.log('got '+Object.keys(cachedData.result.map).length+' data tiles from cache');
|
// if everything was cached, we immediately end the render pass
|
||||||
if(Object.keys(cachedData.result.map).length > 0) {
|
// otherwise, the render pass will be ended in the callbacks
|
||||||
handleDataResponse(cachedData, true);
|
render.endRenderPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle failed map data request
|
// Handle failed map data request
|
||||||
@ -199,8 +203,9 @@ window.handleFailedRequest = function(tile_ids) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(requests.isLastRequest('getThinnedEntitiesV4')) {
|
if(requests.isLastRequest('getThinnedEntitiesV4')) {
|
||||||
var leftOverPortals = portalRenderLimit.mergeLowLevelPortals(null);
|
render.endRenderPass();
|
||||||
handlePortalsRender(leftOverPortals);
|
// var leftOverPortals = portalRenderLimit.mergeLowLevelPortals(null);
|
||||||
|
// handlePortalsRender(leftOverPortals);
|
||||||
}
|
}
|
||||||
runHooks('requestFinished', {success: false});
|
runHooks('requestFinished', {success: false});
|
||||||
}
|
}
|
||||||
@ -255,661 +260,19 @@ window.handleDataResponse = function(data, fromCache, tile_ids) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$.each(val.deletedGameEntityGuids || [], function(ind, guid) {
|
render.processTileData(val);
|
||||||
// avoid processing a delete we've already done
|
|
||||||
if (guid in window._deletedEntityGuid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// store that we've processed it
|
|
||||||
window._deletedEntityGuid[guid] = true;
|
|
||||||
|
|
||||||
// if the deleted entity is a field, remove this field from the linkedFields entries for any portals
|
|
||||||
if(getTypeByGuid(guid) === TYPE_FIELD && window.fields[guid] !== undefined) {
|
|
||||||
$.each(window.fields[guid].options.vertices, function(ind, vertex) {
|
|
||||||
if(window.portals[vertex.guid] === undefined) return true;
|
|
||||||
fieldArray = window.portals[vertex.guid].options.details.portalV2.linkedFields;
|
|
||||||
fieldArray.splice($.inArray(guid, fieldArray), 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO? if the deleted entity is a link, remove it from any portals linkedEdges
|
|
||||||
|
|
||||||
window.removeByGuid(guid);
|
|
||||||
});
|
|
||||||
|
|
||||||
$.each(val.gameEntities || [], function(ind, ent) {
|
|
||||||
// ent = [GUID, id(?), details]
|
|
||||||
// format for links: { controllingTeam, creator, edge }
|
|
||||||
// format for portals: { controllingTeam, turret }
|
|
||||||
|
|
||||||
// skip entities in the deleted list
|
|
||||||
if(ent[0] in window._deletedEntityGuid) return true;
|
|
||||||
|
|
||||||
|
|
||||||
if(ent[2].turret !== undefined) {
|
|
||||||
// TODO? remove any linkedEdges or linkedFields that have entries in window._deletedEntityGuid
|
|
||||||
|
|
||||||
var latlng = [ent[2].locationE6.latE6/1E6, ent[2].locationE6.lngE6/1E6];
|
|
||||||
if(!window.getPaddedBounds().contains(latlng)
|
|
||||||
&& selectedPortal !== ent[0]
|
|
||||||
&& urlPortal !== ent[0]
|
|
||||||
&& !(urlPortalLL && urlPortalLL[0] === latlng[0] && urlPortalLL[1] === latlng[1])
|
|
||||||
) 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[ent[0]] = ent; // delay portal render
|
|
||||||
} else if(ent[2].edge !== undefined) {
|
|
||||||
renderLink(ent);
|
|
||||||
} else if(ent[2].capturedRegion !== undefined) {
|
|
||||||
$.each(ent[2].capturedRegion, function(ind, vertex) {
|
|
||||||
if(p2f[vertex.guid] === undefined)
|
|
||||||
p2f[vertex.guid] = new Array();
|
|
||||||
p2f[vertex.guid].push(ent[0]);
|
|
||||||
});
|
|
||||||
renderField(ent);
|
|
||||||
} else {
|
|
||||||
throw('Unknown entity: ' + JSON.stringify(ent));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$.each(ppp, function(ind, portal) {
|
|
||||||
// when both source and destination portal are in the same response, no explicit 'edge' is returned
|
|
||||||
// instead, we need to reconstruct them from the data within the portal details
|
|
||||||
|
|
||||||
if ('portalV2' in portal[2] && 'linkedEdges' in portal[2].portalV2) {
|
|
||||||
$.each(portal[2].portalV2.linkedEdges, function (ind, edge) {
|
|
||||||
// don't reconstruct deleted links
|
|
||||||
if (edge.edgeGuid in window._deletedEntityGuid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// no data for other portal - can't reconstruct
|
|
||||||
if (!ppp[edge.otherPortalGuid])
|
|
||||||
return;
|
|
||||||
|
|
||||||
var otherportal = ppp[edge.otherPortalGuid];
|
|
||||||
|
|
||||||
// check other portal has matching data for the reverse direction
|
|
||||||
var hasOtherEdge = false;
|
|
||||||
|
|
||||||
if ('portalV2' in otherportal[2] && 'linkedEdges' in otherportal[2].portalV2) {
|
|
||||||
$.each(otherportal[2].portalV2.linkedEdges, function(otherind, otheredge) {
|
|
||||||
if (otheredge.edgeGuid == edge.edgeGuid) {
|
|
||||||
hasOtherEdge = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasOtherEdge)
|
|
||||||
return;
|
|
||||||
|
|
||||||
renderLink([
|
|
||||||
edge.edgeGuid,
|
|
||||||
0, // link data modified time - set to 0 as it's unknown
|
|
||||||
{
|
|
||||||
"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'] = [];
|
|
||||||
}
|
|
||||||
if(p2f[portal[0]] !== undefined) {
|
|
||||||
$.merge(p2f[portal[0]], portal[2].portalV2['linkedFields']);
|
|
||||||
portal[2].portalV2['linkedFields'] = uniqueArray(p2f[portal[0]]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Process the portals with portal render limit handler first
|
|
||||||
// Low level portal will hold until last request
|
|
||||||
var newPpp = portalRenderLimit.splitOrMergeLowLevelPortals(ppp);
|
|
||||||
// Clean up level of portal which over render limit after portalRenderLimit handler counted the new portals
|
|
||||||
portalRenderLimit.cleanUpOverLimitPortalLevel();
|
|
||||||
handlePortalsRender(newPpp);
|
|
||||||
|
|
||||||
resolvePlayerNames();
|
resolvePlayerNames();
|
||||||
renderUpdateStatus();
|
renderUpdateStatus();
|
||||||
|
|
||||||
|
if(requests.isLastRequest('getThinnedEntitiesV4')) {
|
||||||
|
render.endRenderPass();
|
||||||
|
// var leftOverPortals = portalRenderLimit.mergeLowLevelPortals(null);
|
||||||
|
// handlePortalsRender(leftOverPortals);
|
||||||
|
}
|
||||||
runHooks('requestFinished', {success: true});
|
runHooks('requestFinished', {success: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.handlePortalsRender = function(portals) {
|
|
||||||
var portalInUrlAvailable = false;
|
|
||||||
|
|
||||||
// Preserve selectedPortal because it will get lost on re-rendering
|
|
||||||
// the portal
|
|
||||||
var oldSelectedPortal = selectedPortal;
|
|
||||||
runHooks('portalDataLoaded', {portals : portals});
|
|
||||||
$.each(portals, function(guid, portal) {
|
|
||||||
//~ if(selectedPortal === portal[0]) portalUpdateAvailable = true;
|
|
||||||
if(urlPortalLL && urlPortalLL[0] === portal[2].locationE6.latE6/1E6 && urlPortalLL[1] === portal[2].locationE6.lngE6/1E6) {
|
|
||||||
urlPortal = guid;
|
|
||||||
portalInUrlAvailable = true;
|
|
||||||
urlPortalLL = null;
|
|
||||||
}
|
|
||||||
if(window.portals[guid]) {
|
|
||||||
highlightPortal(window.portals[guid]);
|
|
||||||
}
|
|
||||||
renderPortal(portal);
|
|
||||||
});
|
|
||||||
|
|
||||||
// restore selected portal if still available
|
|
||||||
var selectedPortalGroup = portals[oldSelectedPortal];
|
|
||||||
if(selectedPortalGroup) {
|
|
||||||
selectedPortal = oldSelectedPortal;
|
|
||||||
renderPortalDetails(selectedPortal);
|
|
||||||
try {
|
|
||||||
selectedPortalGroup.bringToFront();
|
|
||||||
} catch(e) { /* portal is now visible, catch Leaflet error */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
if(portalInUrlAvailable) {
|
|
||||||
renderPortalDetails(urlPortal);
|
|
||||||
urlPortal = null; // select it only once
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// removes entities that are still handled by Leaflet, although they
|
|
||||||
// do not intersect the current viewport.
|
|
||||||
window.cleanUp = function() {
|
|
||||||
var cnt = [0,0,0];
|
|
||||||
var b = getPaddedBounds();
|
|
||||||
var minlvl = getMinPortalLevel();
|
|
||||||
for(var i = 0; i < portalsLayers.length; i++) {
|
|
||||||
// i is also the portal level
|
|
||||||
portalsLayers[i].eachLayer(function(item) {
|
|
||||||
var itemGuid = item.options.guid;
|
|
||||||
// check if 'item' is a portal
|
|
||||||
if(getTypeByGuid(itemGuid) != TYPE_PORTAL) return true;
|
|
||||||
// portal must be in bounds and have a high enough level. Also don’t
|
|
||||||
// remove if it is selected.
|
|
||||||
if(itemGuid == window.selectedPortal ||
|
|
||||||
(b.contains(item.getLatLng()) && i >= minlvl)) return true;
|
|
||||||
cnt[0]++;
|
|
||||||
portalsLayers[i].removeLayer(item);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
linksLayer.eachLayer(function(link) {
|
|
||||||
if(b.intersects(link.getBounds())) return;
|
|
||||||
cnt[1]++;
|
|
||||||
linksLayer.removeLayer(link);
|
|
||||||
});
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// removes given entity from map
|
|
||||||
window.removeByGuid = function(guid) {
|
|
||||||
switch(getTypeByGuid(guid)) {
|
|
||||||
case TYPE_PORTAL:
|
|
||||||
if(!window.portals[guid]) return;
|
|
||||||
var p = window.portals[guid];
|
|
||||||
for(var i = 0; i < portalsLayers.length; i++)
|
|
||||||
portalsLayers[i].removeLayer(p);
|
|
||||||
break;
|
|
||||||
case TYPE_LINK:
|
|
||||||
if(!window.links[guid]) return;
|
|
||||||
linksLayer.removeLayer(window.links[guid]);
|
|
||||||
break;
|
|
||||||
case TYPE_FIELD:
|
|
||||||
if(!window.fields[guid]) return;
|
|
||||||
fieldsLayer.removeLayer(window.fields[guid]);
|
|
||||||
break;
|
|
||||||
case TYPE_RESONATOR:
|
|
||||||
if(!window.resonators[guid]) return;
|
|
||||||
var r = window.resonators[guid];
|
|
||||||
for(var i = 1; i < portalsLayers.length; i++)
|
|
||||||
portalsLayers[i].removeLayer(r);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.warn('unknown GUID type: ' + guid);
|
|
||||||
//window.debug.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Separation of marker style setting from the renderPortal method
|
|
||||||
// Having this as a separate function allows subsituting alternate marker rendering (for plugins)
|
|
||||||
window.getMarker = function(ent, portalLevel, latlng, team) {
|
|
||||||
var lvWeight = Math.max(2, Math.floor(portalLevel) / 1.5);
|
|
||||||
var lvRadius = Math.floor(portalLevel) + 4;
|
|
||||||
if(team === window.TEAM_NONE) {
|
|
||||||
lvRadius = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
var p = L.circleMarker(latlng, {
|
|
||||||
radius: lvRadius + (L.Browser.mobile ? PORTAL_RADIUS_ENLARGE_MOBILE : 0),
|
|
||||||
color: ent[0] === selectedPortal ? COLOR_SELECTED_PORTAL : COLORS[team],
|
|
||||||
opacity: 1,
|
|
||||||
weight: lvWeight,
|
|
||||||
fillColor: COLORS[team],
|
|
||||||
fillOpacity: 0.5,
|
|
||||||
clickable: true,
|
|
||||||
level: portalLevel,
|
|
||||||
team: team,
|
|
||||||
ent: ent,
|
|
||||||
details: ent[2],
|
|
||||||
guid: ent[0]});
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// renders a portal on the map from the given entity
|
|
||||||
window.renderPortal = function(ent) {
|
|
||||||
if(window.portalsCount >= MAX_DRAWN_PORTALS && ent[0] !== selectedPortal)
|
|
||||||
return removeByGuid(ent[0]);
|
|
||||||
|
|
||||||
// hide low level portals on low zooms
|
|
||||||
var portalLevel = getPortalLevel(ent[2]);
|
|
||||||
if(portalLevel < getMinPortalLevel() && ent[0] !== selectedPortal)
|
|
||||||
return removeByGuid(ent[0]);
|
|
||||||
|
|
||||||
var team = getTeam(ent[2]);
|
|
||||||
|
|
||||||
// do nothing if portal did not change
|
|
||||||
var layerGroup = portalsLayers[parseInt(portalLevel)];
|
|
||||||
var old = findEntityInLeaflet(layerGroup, window.portals, ent[0]);
|
|
||||||
if(!changing_highlighters && old) {
|
|
||||||
var oo = old.options;
|
|
||||||
|
|
||||||
// if the data we have is older than/the same as the data already rendered, do nothing
|
|
||||||
if (oo.ent[1] >= ent[1]) {
|
|
||||||
// let resos handle themselves if they need to be redrawn
|
|
||||||
renderResonators(ent[0], ent[2], old);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default checks to see if a portal needs to be re-rendered
|
|
||||||
var u = oo.team !== team;
|
|
||||||
u = u || oo.level !== portalLevel;
|
|
||||||
|
|
||||||
// Allow plugins to add additional conditions as to when a portal gets re-rendered
|
|
||||||
var hookData = {portal: ent[2], oldPortal: oo.details, portalGuid: ent[0], mtime: ent[1], oldMtime: oo.ent[1], reRender: false};
|
|
||||||
runHooks('beforePortalReRender', hookData);
|
|
||||||
u = u || hookData.reRender;
|
|
||||||
|
|
||||||
// nothing changed that requires re-rendering the portal.
|
|
||||||
if(!u) {
|
|
||||||
// let resos handle themselves if they need to be redrawn
|
|
||||||
renderResonators(ent[0], ent[2], old);
|
|
||||||
// update stored details for portal details in sidebar.
|
|
||||||
old.options.details = ent[2];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// there were changes, remove old portal. Don’t put this in old, in
|
|
||||||
// case the portal changed level and findEntityInLeaflet doesn’t find
|
|
||||||
// it.
|
|
||||||
removeByGuid(ent[0]);
|
|
||||||
|
|
||||||
var latlng = [ent[2].locationE6.latE6/1E6, ent[2].locationE6.lngE6/1E6];
|
|
||||||
|
|
||||||
// pre-loads player names for high zoom levels
|
|
||||||
loadPlayerNamesForPortal(ent[2]);
|
|
||||||
|
|
||||||
var p = getMarker(ent, portalLevel, latlng, team);
|
|
||||||
|
|
||||||
p.on('remove', function() {
|
|
||||||
var portalGuid = this.options.guid
|
|
||||||
|
|
||||||
// remove attached resonators, skip if
|
|
||||||
// all resonators have already removed by zooming
|
|
||||||
if(isResonatorsShow()) {
|
|
||||||
for(var i = 0; i <= 7; i++)
|
|
||||||
removeByGuid(portalResonatorGuid(portalGuid, i));
|
|
||||||
}
|
|
||||||
delete window.portals[portalGuid];
|
|
||||||
window.portalsCount --;
|
|
||||||
if(window.selectedPortal === portalGuid) {
|
|
||||||
window.unselectOldPortal();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
p.on('add', function() {
|
|
||||||
// enable for debugging
|
|
||||||
if(window.portals[this.options.guid]) throw('duplicate portal detected');
|
|
||||||
window.portals[this.options.guid] = this;
|
|
||||||
window.portalsCount ++;
|
|
||||||
|
|
||||||
window.renderResonators(this.options.guid, this.options.details, this);
|
|
||||||
// handles the case where a selected portal gets removed from the
|
|
||||||
// map by hiding all portals with said level
|
|
||||||
if(window.selectedPortal !== this.options.guid)
|
|
||||||
window.portalResetColor(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
p.on('click', function() { window.renderPortalDetails(ent[0]); });
|
|
||||||
p.on('dblclick', function() {
|
|
||||||
window.renderPortalDetails(ent[0]);
|
|
||||||
window.map.setView(latlng, 17);
|
|
||||||
});
|
|
||||||
|
|
||||||
highlightPortal(p);
|
|
||||||
window.runHooks('portalAdded', {portal: p});
|
|
||||||
p.addTo(layerGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.renderResonators = function(portalGuid, portalDetails, portalLayer) {
|
|
||||||
if(!isResonatorsShow()) return;
|
|
||||||
|
|
||||||
// only draw when the portal is not hidden
|
|
||||||
if(portalLayer && !window.map.hasLayer(portalLayer)) return;
|
|
||||||
|
|
||||||
var portalLevel = getPortalLevel(portalDetails);
|
|
||||||
var portalLatLng = [portalDetails.locationE6.latE6/1E6, portalDetails.locationE6.lngE6/1E6];
|
|
||||||
|
|
||||||
var reRendered = false;
|
|
||||||
$.each(portalDetails.resonatorArray.resonators, function(i, rdata) {
|
|
||||||
// skip if resonator didn't change
|
|
||||||
var oldRes = window.resonators[portalResonatorGuid(portalGuid, i)];
|
|
||||||
if(oldRes) {
|
|
||||||
if(isSameResonator(oldRes.options.details, rdata)) return true;
|
|
||||||
// remove old resonator if exist
|
|
||||||
removeByGuid(oldRes.options.guid);
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip and remove old resonator if no new resonator
|
|
||||||
if(rdata === null) return true;
|
|
||||||
|
|
||||||
var resoLatLng = getResonatorLatLng(rdata.distanceToPortal, rdata.slot, portalLatLng);
|
|
||||||
var resoGuid = portalResonatorGuid(portalGuid, i);
|
|
||||||
|
|
||||||
// the resonator
|
|
||||||
var resoStyle =
|
|
||||||
portalGuid === selectedPortal ? OPTIONS_RESONATOR_SELECTED : OPTIONS_RESONATOR_NON_SELECTED;
|
|
||||||
var resoProperty = $.extend({
|
|
||||||
fillColor: COLORS_LVL[rdata.level],
|
|
||||||
fillOpacity: rdata.energyTotal/RESO_NRG[rdata.level],
|
|
||||||
guid: resoGuid
|
|
||||||
}, resoStyle);
|
|
||||||
|
|
||||||
var reso = L.circleMarker(resoLatLng, resoProperty);
|
|
||||||
|
|
||||||
// line connecting reso to portal
|
|
||||||
var connProperty =
|
|
||||||
portalGuid === selectedPortal ? OPTIONS_RESONATOR_LINE_SELECTED : OPTIONS_RESONATOR_LINE_NON_SELECTED;
|
|
||||||
|
|
||||||
var conn = L.polyline([portalLatLng, resoLatLng], connProperty);
|
|
||||||
|
|
||||||
// put both in one group, so they can be handled by the same logic.
|
|
||||||
var r = L.layerGroup([reso, conn]);
|
|
||||||
r.options = {
|
|
||||||
level: rdata.level,
|
|
||||||
details: rdata,
|
|
||||||
pDetails: portalDetails,
|
|
||||||
guid: resoGuid
|
|
||||||
};
|
|
||||||
|
|
||||||
// However, LayerGroups (and FeatureGroups) don’t fire add/remove
|
|
||||||
// events, thus this listener will be attached to the resonator. It
|
|
||||||
// doesn’t matter to which element these are bound since Leaflet
|
|
||||||
// will add/remove all elements of the LayerGroup at once.
|
|
||||||
reso.on('remove', function() { delete window.resonators[this.options.guid]; });
|
|
||||||
reso.on('add', function() {
|
|
||||||
if(window.resonators[this.options.guid]) throw('duplicate resonator detected');
|
|
||||||
window.resonators[this.options.guid] = r;
|
|
||||||
});
|
|
||||||
|
|
||||||
r.addTo(portalsLayers[parseInt(portalLevel)]);
|
|
||||||
reRendered = true;
|
|
||||||
});
|
|
||||||
// if there is any resonator re-rendered, bring portal to front
|
|
||||||
if(reRendered && portalLayer) portalLayer.bringToFront();
|
|
||||||
}
|
|
||||||
|
|
||||||
// append portal guid with -resonator-[slot] to get guid for resonators
|
|
||||||
window.portalResonatorGuid = function(portalGuid, slot) {
|
|
||||||
return portalGuid + '-resonator-' + slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.isResonatorsShow = function() {
|
|
||||||
return map.getZoom() >= RESONATOR_DISPLAY_ZOOM_LEVEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
if(oldRes.distanceToPortal !== newRes.distanceToPortal) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.portalResetColor = function(portal) {
|
|
||||||
portal.setStyle({color: COLORS[getTeam(portal.options.details)]});
|
|
||||||
resonatorsResetStyle(portal.options.guid);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.resonatorsResetStyle = function(portalGuid) {
|
|
||||||
window.resonatorsSetStyle(portalGuid, OPTIONS_RESONATOR_NON_SELECTED, OPTIONS_RESONATOR_LINE_NON_SELECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.resonatorsSetSelectStyle = function(portalGuid) {
|
|
||||||
window.resonatorsSetStyle(portalGuid, OPTIONS_RESONATOR_SELECTED, OPTIONS_RESONATOR_LINE_SELECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.resonatorsSetStyle = function(portalGuid, resoStyle, lineStyle) {
|
|
||||||
for(var i = 0; i < 8; i++) {
|
|
||||||
resonatorLayerGroup = resonators[portalResonatorGuid(portalGuid, i)];
|
|
||||||
if(!resonatorLayerGroup) continue;
|
|
||||||
// bring resonators and their connection lines to front separately.
|
|
||||||
// this way the resonators are drawn on top of the lines.
|
|
||||||
resonatorLayerGroup.eachLayer(function(layer) {
|
|
||||||
if (!layer.options.guid) // Resonator line
|
|
||||||
layer.bringToFront().setStyle(lineStyle);
|
|
||||||
});
|
|
||||||
resonatorLayerGroup.eachLayer(function(layer) {
|
|
||||||
if (layer.options.guid) // Resonator
|
|
||||||
layer.bringToFront().setStyle(resoStyle);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
portals[portalGuid].bringToFront();
|
|
||||||
}
|
|
||||||
|
|
||||||
// renders a link on the map from the given entity
|
|
||||||
window.renderLink = function(ent) {
|
|
||||||
if(window.linksCount >= MAX_DRAWN_LINKS)
|
|
||||||
return removeByGuid(ent[0]);
|
|
||||||
|
|
||||||
// some links are constructed from portal linkedEdges data. These have no valid 'creator' data.
|
|
||||||
// replace with the more detailed data
|
|
||||||
// (we assume the other values - coordinates, etc - remain unchanged)
|
|
||||||
var found=findEntityInLeaflet(linksLayer, links, ent[0]);
|
|
||||||
if (found) {
|
|
||||||
if (!found.options.data.creator && ent[2].creator) {
|
|
||||||
//our existing data has no creator, but the new data does - update
|
|
||||||
found.options.data = ent[2];
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var team = getTeam(ent[2]);
|
|
||||||
var edge = ent[2].edge;
|
|
||||||
var latlngs = [
|
|
||||||
[edge.originPortalLocation.latE6/1E6, edge.originPortalLocation.lngE6/1E6],
|
|
||||||
[edge.destinationPortalLocation.latE6/1E6, edge.destinationPortalLocation.lngE6/1E6]
|
|
||||||
];
|
|
||||||
var poly = L.geodesicPolyline(latlngs, {
|
|
||||||
color: COLORS[team],
|
|
||||||
opacity: 1,
|
|
||||||
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;
|
|
||||||
poly.projectLatlngs();
|
|
||||||
var op = poly._originalPoints;
|
|
||||||
var dist = Math.abs(op[0].x - op[1].x) + Math.abs(op[0].y - op[1].y);
|
|
||||||
if(dist <= 10) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!getPaddedBounds().intersects(poly.getBounds())) return;
|
|
||||||
|
|
||||||
poly.on('remove', function() {
|
|
||||||
delete window.links[this.options.guid];
|
|
||||||
window.linksCount--;
|
|
||||||
});
|
|
||||||
poly.on('add', function() {
|
|
||||||
// enable for debugging
|
|
||||||
if(window.links[this.options.guid]) throw('duplicate link detected');
|
|
||||||
window.links[this.options.guid] = this;
|
|
||||||
window.linksCount++;
|
|
||||||
this.bringToBack();
|
|
||||||
});
|
|
||||||
poly.addTo(linksLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// renders a field on the map from a given entity
|
|
||||||
window.renderField = function(ent) {
|
|
||||||
if(window.fieldsCount >= 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)
|
|
||||||
];
|
|
||||||
|
|
||||||
var poly = L.geodesicPolygon(latlngs, {
|
|
||||||
fillColor: COLORS[team],
|
|
||||||
fillOpacity: 0.25,
|
|
||||||
stroke: false,
|
|
||||||
clickable: false,
|
|
||||||
smoothFactor: 0, // hiding small fields will be handled below
|
|
||||||
guid: ent[0]});
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// low amount of fields there isn’t much to gain.
|
|
||||||
// The algorithm is the same as used by Leaflet.
|
|
||||||
poly._map = window.map;
|
|
||||||
poly.projectLatlngs();
|
|
||||||
var count = L.LineUtil.simplify(poly._originalPoints, 6).length;
|
|
||||||
if(count <= 2) return;
|
|
||||||
|
|
||||||
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) 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];
|
|
||||||
window.fieldsCount--;
|
|
||||||
});
|
|
||||||
poly.on('add', function() {
|
|
||||||
// enable for debugging
|
|
||||||
if(window.fields[this.options.guid]) console.warn('duplicate field detected');
|
|
||||||
window.fields[this.options.guid] = f;
|
|
||||||
window.fieldsCount++;
|
|
||||||
this.bringToBack();
|
|
||||||
});
|
|
||||||
f.addTo(fieldsLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// looks for the GUID in either the layerGroup or entityHash, depending
|
|
||||||
// on which is faster. Will either return the Leaflet entity or null, if
|
|
||||||
// it does not exist.
|
|
||||||
// For example, to find a field use the function like this:
|
|
||||||
// field = findEntityInLeaflet(fieldsLayer, fields, 'asdasdasd');
|
|
||||||
window.findEntityInLeaflet = function(layerGroup, entityHash, guid) {
|
|
||||||
// fast way
|
|
||||||
if(map.hasLayer(layerGroup)) return entityHash[guid] || null;
|
|
||||||
|
|
||||||
// slow way in case the layer is currently hidden
|
|
||||||
var ent = null;
|
|
||||||
layerGroup.eachLayer(function(entity) {
|
|
||||||
if(entity.options.guid !== guid) return true;
|
|
||||||
ent = entity;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
@ -13,16 +13,20 @@ window.Render.prototype.startRenderPass = function() {
|
|||||||
this.isRendering = true;
|
this.isRendering = true;
|
||||||
|
|
||||||
this.deletedGuid = {}; // object - represents the set of all deleted game entity GUIDs seen in a render pass
|
this.deletedGuid = {}; // object - represents the set of all deleted game entity GUIDs seen in a render pass
|
||||||
|
|
||||||
|
this.seenPortalsGuid = {};
|
||||||
|
this.seenLinksGuid = {};
|
||||||
|
this.seenFieldsGuid = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// process deleted entity list and entity data
|
// process deleted entity list and entity data
|
||||||
window.Render.prototype.processTileData = function(deleted, entities) {
|
window.Render.prototype.processTileData = function(tiledata) {
|
||||||
this.processDeletedGameEntityGuids(deleted);
|
this.processDeletedGameEntityGuids(tiledata.deletedGameEntityGuids||[]);
|
||||||
this.processGameEntities(entities);
|
this.processGameEntities(tiledata.gameEntities||[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
window.Render.prototype.processDeletedGamEntityGuids = function(deleted) {
|
window.Render.prototype.processDeletedGameEntityGuids = function(deleted) {
|
||||||
for(var i in deleted) {
|
for(var i in deleted) {
|
||||||
var guid = deleted[i];
|
var guid = deleted[i];
|
||||||
|
|
||||||
@ -49,8 +53,7 @@ window.Render.prototype.processGameEntities = function(entities) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: reconstruct links 'optimised' out of the data from the portal link data
|
// now reconstruct links 'optimised' out of the data from the portal link data
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,29 +61,58 @@ window.Render.prototype.processGameEntities = function(entities) {
|
|||||||
// is considered complete
|
// is considered complete
|
||||||
window.Render.prototype.endRenderPass = function() {
|
window.Render.prototype.endRenderPass = function() {
|
||||||
|
|
||||||
|
// check to see if there's eny entities we haven't seen. if so, delete them
|
||||||
|
for (var guid in window.portals) {
|
||||||
|
if (!(guid in this.seenPortalsGuid)) {
|
||||||
|
this.deletePortalEntity(guid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var guid in window.links) {
|
||||||
|
if (!(guid in this.seenLinksGuid)) {
|
||||||
|
this.deleteLinkEntity(guid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var guid in window.fields) {
|
||||||
|
if (!(guid in this.seenFieldsGuid)) {
|
||||||
|
this.deleteFieldEntity(guid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.isRendering = false;
|
this.isRendering = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
window.Render.prototype.deleteEntity = function(guid) {
|
window.Render.prototype.deleteEntity = function(guid) {
|
||||||
|
this.deletePortalEntity(guid);
|
||||||
|
this.deleteLinkEntity(guid);
|
||||||
|
this.deleteFieldEntity(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Render.prototype.deletePortalEntity = function(guid) {
|
||||||
if (guid in window.portals) {
|
if (guid in window.portals) {
|
||||||
var p = window.portals[guid];
|
var p = window.portals[guid];
|
||||||
for(var i in portalsLayers) {
|
for(var i in portalsLayers) {
|
||||||
portalsLayers[i].removeLayer(p);
|
portalsLayers[i].removeLayer(p);
|
||||||
}
|
}
|
||||||
delete window.portals[guid];
|
delete window.portals[guid];
|
||||||
} else if (guid in window.links) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Render.prototype.deleteLinkEntity = function(guid) {
|
||||||
|
if (guid in window.links) {
|
||||||
var l = window.links[guid];
|
var l = window.links[guid];
|
||||||
linksLayer.removeLayer(l);
|
linksLayer.removeLayer(l);
|
||||||
delete window.links[guid];
|
delete window.links[guid];
|
||||||
} else if (guid in window.fields) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Render.prototype.deleteFieldEntity = function(guid) {
|
||||||
|
if (guid in window.fields) {
|
||||||
var f = window.fields[guid];
|
var f = window.fields[guid];
|
||||||
fieldsLayer.removeLayer[guid];
|
fieldsLayer.removeLayer(f);
|
||||||
delete window.fields[f];
|
delete window.fields[f];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -106,6 +138,8 @@ window.Render.prototype.createEntity = function(ent) {
|
|||||||
|
|
||||||
|
|
||||||
window.Render.prototype.createPortalEntity = function(ent) {
|
window.Render.prototype.createPortalEntity = function(ent) {
|
||||||
|
this.seenPortalsGuid[ent[0]] = true; // flag we've seen it
|
||||||
|
|
||||||
// check if entity already exists
|
// check if entity already exists
|
||||||
if (ent[0] in window.portals) {
|
if (ent[0] in window.portals) {
|
||||||
// yes. now check to see if the entity data we have is newer than that in place
|
// yes. now check to see if the entity data we have is newer than that in place
|
||||||
@ -117,13 +151,13 @@ window.Render.prototype.createPortalEntity = function(ent) {
|
|||||||
// (e.g. level changed, so size is different, or stats changed so highlighter is different)
|
// (e.g. level changed, so size is different, or stats changed so highlighter is different)
|
||||||
// so to keep things simple we'll always re-create the entity in this case
|
// so to keep things simple we'll always re-create the entity in this case
|
||||||
|
|
||||||
deleteEntity(ent[0]);
|
this.deletePortalEntity(ent[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var portalLevel = getPortalLevel(ent[2]);
|
var portalLevel = getPortalLevel(ent[2]);
|
||||||
var team = getTeam(ent[2]);
|
var team = getTeam(ent[2]);
|
||||||
|
|
||||||
var latlng = L.latlng(ent[2].locationE6.latE6/1E6, ent[2].locationE6.lngE6/1E6);
|
var latlng = L.latLng(ent[2].locationE6.latE6/1E6, ent[2].locationE6.lngE6/1E6);
|
||||||
|
|
||||||
var marker = this.createMarker(ent, portalLevel, latlng, team);
|
var marker = this.createMarker(ent, portalLevel, latlng, team);
|
||||||
|
|
||||||
@ -172,6 +206,8 @@ window.Render.prototype.portalPolyOptions = function(ent, portalLevel, team) {
|
|||||||
|
|
||||||
|
|
||||||
window.Render.prototype.createFieldEntity = function(ent) {
|
window.Render.prototype.createFieldEntity = function(ent) {
|
||||||
|
this.seenFieldsGuid[ent[0]] = true; // flag we've seen it
|
||||||
|
|
||||||
// check if entity already exists
|
// check if entity already exists
|
||||||
if(ent[0] in window.fields) {
|
if(ent[0] in window.fields) {
|
||||||
// yes. in theory, we should never get updated data for an existing field. they're created, and they're destroyed - never changed
|
// yes. in theory, we should never get updated data for an existing field. they're created, and they're destroyed - never changed
|
||||||
@ -183,7 +219,7 @@ window.Render.prototype.createFieldEntity = function(ent) {
|
|||||||
// the data we have is newer - two options
|
// the data we have is newer - two options
|
||||||
// 1. just update the data, assume the field render appearance is unmodified
|
// 1. just update the data, assume the field render appearance is unmodified
|
||||||
// 2. delete the entity, then re-create with the new data
|
// 2. delete the entity, then re-create with the new data
|
||||||
deleteEntity(ent[0]); // option 2, for now
|
this.deleteFieldEntity(ent[0]); // option 2, for now
|
||||||
}
|
}
|
||||||
|
|
||||||
var team = getTeam(ent[2]);
|
var team = getTeam(ent[2]);
|
||||||
@ -212,6 +248,8 @@ window.Render.prototype.createFieldEntity = function(ent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.Render.prototype.createLinkEntity = function(ent) {
|
window.Render.prototype.createLinkEntity = function(ent) {
|
||||||
|
this.seenLinksGuid[ent[0]] = true; // flag we've seen it
|
||||||
|
|
||||||
// check if entity already exists
|
// check if entity already exists
|
||||||
if (ent[0] in window.links) {
|
if (ent[0] in window.links) {
|
||||||
// yes. now, as sometimes links are 'faked', they have incomplete data. if the data we have is better, replace the data
|
// yes. now, as sometimes links are 'faked', they have incomplete data. if the data we have is better, replace the data
|
||||||
@ -223,14 +261,14 @@ window.Render.prototype.createLinkEntity = function(ent) {
|
|||||||
// the data is newer/better - two options
|
// the data is newer/better - two options
|
||||||
// 1. just update the data. assume the link render appearance is unmodified
|
// 1. just update the data. assume the link render appearance is unmodified
|
||||||
// 2. delete the entity, then re-create it with the new data
|
// 2. delete the entity, then re-create it with the new data
|
||||||
deleteEntity(ent[0]); // option 2 - for now
|
this.deleteLinkEntity(ent[0]); // option 2 - for now
|
||||||
}
|
}
|
||||||
|
|
||||||
var team = getTeam(ent[2]);
|
var team = getTeam(ent[2]);
|
||||||
var edge = ent[2].edge;
|
var edge = ent[2].edge;
|
||||||
var latlngs = [
|
var latlngs = [
|
||||||
L.latlng(edge.originPortalLocation.latE6/1E6, edge.originPortalLocation.lngE6/1E6),
|
L.latLng(edge.originPortalLocation.latE6/1E6, edge.originPortalLocation.lngE6/1E6),
|
||||||
L.latlng(edge.destinationPortalLocation.latE6/1E6, edge.destinationPortalLocation.lngE6/1E6)
|
L.latLng(edge.destinationPortalLocation.latE6/1E6, edge.destinationPortalLocation.lngE6/1E6)
|
||||||
];
|
];
|
||||||
var poly = L.geodesicPolyline(latlngs, {
|
var poly = L.geodesicPolyline(latlngs, {
|
||||||
color: COLORS[team],
|
color: COLORS[team],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user