250 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // MAP DATA RENDER ////////////////////////////////////////////////
 | |
| // class to handle rendering into leaflet the JSON data from the servers
 | |
| 
 | |
| 
 | |
| 
 | |
| window.Render = function() {
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| // start a render pass. called as we start to make the batch of data requests to the servers
 | |
| window.Render.prototype.startRenderPass = function() {
 | |
|   this.isRendering = true;
 | |
| 
 | |
|   this.deletedGuid = {};  // object - represents the set of all deleted game entity GUIDs seen in a render pass
 | |
| }
 | |
| 
 | |
| // process deleted entity list and entity data
 | |
| window.Render.prototype.processTileData = function(deleted, entities) {
 | |
|   this.processDeletedGameEntityGuids(deleted);
 | |
|   this.processGameEntities(entities);
 | |
| }
 | |
| 
 | |
| 
 | |
| window.Render.prototype.processDeletedGamEntityGuids = function(deleted) {
 | |
|   for(var i in deleted) {
 | |
|     var guid = deleted[i];
 | |
| 
 | |
|     if ( !(guid in this.deletedGuid) ) {
 | |
|       this.deletedGuid[guid] = true;  // flag this guid as having being processed
 | |
| 
 | |
|       // the original code this is based on checked to see if the guid was for a field - and if so, removed it from the linkedFields of the relevant portals
 | |
|       // given that the server will also return updated portals - and the linkedFields data is not actively used in IITC, this seems pointless.
 | |
| 
 | |
|       this.deleteEntity(guid);
 | |
| 
 | |
|     }
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| window.Render.prototype.processGameEntities = function(entities) {
 | |
|   for (var i in entities) {
 | |
|     var ent = entities[i];
 | |
| 
 | |
|     // don't create entities in the 'deleted' list
 | |
|     if (!(ent[0] in this.deletedGuid)) {
 | |
|       this.createEntity(ent);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // TODO: reconstruct links 'optimised' out of the data from the portal link data
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| // end a render pass. does any cleaning up required, postponed processing of data, etc. called when the render
 | |
| // is considered complete
 | |
| window.Render.prototype.endRenderPass = function() {
 | |
| 
 | |
|   this.isRendering = false;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| window.Render.prototype.deleteEntity = function(guid) {
 | |
| 
 | |
|   if (guid in window.portals) {
 | |
|     var p = window.portals[guid];
 | |
|     for(var i in portalsLayers) {
 | |
|       portalsLayers[i].removeLayer(p);
 | |
|     }
 | |
|     delete window.portals[guid];
 | |
|   } else if (guid in window.links) {
 | |
|     var l = window.links[guid];
 | |
|     linksLayer.removeLayer(l);
 | |
|     delete window.links[guid];
 | |
|   } else if (guid in window.fields) {
 | |
|     var f = window.fields[guid];
 | |
|     fieldsLayer.removeLayer[guid];
 | |
|     delete window.fields[f];
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| window.Render.prototype.createEntity = function(ent) {
 | |
| 
 | |
|   // ent[0] == guid
 | |
|   // ent[1] == mtime
 | |
|   // ent[2] == data
 | |
| 
 | |
| 
 | |
|   // logic on detecting entity type based on the stock site javascript.
 | |
|   if ("portalV2" in ent[2]) {
 | |
|     this.createPortalEntity(ent);
 | |
|   } else if ("capturedRegion" in ent[2]) {
 | |
|     this.createFieldEntity(ent);
 | |
|   } else if ("edge" in ent[2]) {
 | |
|     this.createLinkEntity(ent);
 | |
|   } else {
 | |
|     console.warn("Unknown entity found: "+JSON.stringify(ent));
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| window.Render.prototype.createPortalEntity = function(ent) {
 | |
|   // check if entity already exists
 | |
|   if (ent[0] in window.portals) {
 | |
|     // yes. now check to see if the entity data we have is newer than that in place
 | |
|     var p = window.portals[ent[0]];
 | |
| 
 | |
|     if (p.options.timestamp >= ent[1]) return; // this data is identical or older - abort processing
 | |
| 
 | |
|     // the data we have is newer. many data changes require re-rendering of the portal
 | |
|     // (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
 | |
| 
 | |
|     deleteEntity(ent[0]);
 | |
|   }
 | |
| 
 | |
|   var portalLevel = getPortalLevel(ent[2]);
 | |
|   var team = getTeam(ent[2]);
 | |
| 
 | |
|   var latlng = L.latlng(ent[2].locationE6.latE6/1E6, ent[2].locationE6.lngE6/1E6);
 | |
| 
 | |
|   var marker = this.createMarker(ent, portalLevel, latlng, team);
 | |
| 
 | |
| 
 | |
|   window.runHooks('portalAdded', {portal: marker});
 | |
| 
 | |
|   window.portals[ent[0]] = marker;
 | |
| 
 | |
|   //TODO? postpone adding to the map layer
 | |
|   portalsLayers[parseInt(portalLevel)].addLayer(marker);
 | |
| 
 | |
| }
 | |
| 
 | |
| window.Render.prototype.createMarker = function(ent, portalLevel, latlng, team) {
 | |
| 
 | |
|   var options = this.portalPolyOptions (ent, portalLevel, team);
 | |
| 
 | |
|   var marker = L.circleMarker (latlng, options);
 | |
| 
 | |
|   return marker;
 | |
| }
 | |
| 
 | |
| window.Render.prototype.portalPolyOptions = function(ent, portalLevel, team) {
 | |
|   var lvWeight = Math.max(2, Math.floor(portalLevel) / 1.5);
 | |
|   var lvRadius = team === window.TEAM_NONE ? 7 : Math.floor(portalLevel) + 4;
 | |
| 
 | |
|   var options = {
 | |
|     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,
 | |
|     guid: ent[0],
 | |
|     timestamp: ent[1],
 | |
|     details: ent[2],
 | |
|     ent: ent // LEGACY - TO BE REMOVED AT SOME POINT! use .guid, .timestamp and .details instead
 | |
|   };
 | |
| 
 | |
|   return options;
 | |
| }
 | |
| 
 | |
| 
 | |
| window.Render.prototype.createFieldEntity = function(ent) {
 | |
|   // check if entity already exists
 | |
|   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
 | |
|     // but theory and practice may not be the same thing...
 | |
|     var f = window.fields[ent[0]];
 | |
| 
 | |
|     if (f.options.timestamp >= ent[1]) return; // this data is identical (or order) than that rendered - abort processing
 | |
| 
 | |
|     // the data we have is newer - two options
 | |
|     // 1. just update the data, assume the field render appearance is unmodified
 | |
|     // 2. delete the entity, then re-create with the new data
 | |
|     deleteEntity(ent[0]); // option 2, for now
 | |
|   }
 | |
| 
 | |
|   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,
 | |
|     guid: ent[0],
 | |
|     timestamp: ent[1],
 | |
|     details: ent[2]
 | |
|   });
 | |
| 
 | |
| 
 | |
|   window.fields[ent[0]] = poly;
 | |
| 
 | |
|   // TODO? postpone adding to the layer??
 | |
|   fieldsLayer.addLayer(poly);
 | |
| }
 | |
| 
 | |
| window.Render.prototype.createLinkEntity = function(ent) {
 | |
|   // check if entity already exists
 | |
|   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
 | |
|     var l = window.links[ent[0]];
 | |
| 
 | |
|     // the faked data will have older timestamps than real data (currently, faked set to zero)
 | |
|     if (l.options.timestamp >= ent[1]) return; // this data is older or identical to the rendered data - abort processing
 | |
| 
 | |
|     // the data is newer/better - two options
 | |
|     // 1. just update the data. assume the link render appearance is unmodified
 | |
|     // 2. delete the entity, then re-create it with the new data
 | |
|     deleteEntity(ent[0]); // option 2 - for now
 | |
|   }
 | |
| 
 | |
|   var team = getTeam(ent[2]);
 | |
|   var edge = ent[2].edge;
 | |
|   var latlngs = [
 | |
|     L.latlng(edge.originPortalLocation.latE6/1E6, edge.originPortalLocation.lngE6/1E6),
 | |
|     L.latlng(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],
 | |
|     timestamp: ent[1],
 | |
|     details: ent[2]
 | |
|   });
 | |
| 
 | |
|   window.links[ent[0]] = poly;
 | |
| 
 | |
|   // TODO? postpone adding to the layer??
 | |
|   linksLayer.addLayer(poly);
 | |
| }
 |