From ff4b036c6ad8b7a7cde0ba5f270b412b7bb22038 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Wed, 24 Aug 2011 14:23:05 +0800 Subject: [PATCH 1/6] Fix accessory face mixing --- src/main/java/org/dynmap/PlayerFaces.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/dynmap/PlayerFaces.java b/src/main/java/org/dynmap/PlayerFaces.java index ef66d128..470d1038 100644 --- a/src/main/java/org/dynmap/PlayerFaces.java +++ b/src/main/java/org/dynmap/PlayerFaces.java @@ -56,12 +56,16 @@ public class PlayerFaces { int[] faceaccessory = new int[64]; /* 8x8 of face accessory */ /* Get buffered image for face at 8x8 */ DynmapBufferedImage face8x8 = DynmapBufferedImage.allocateBufferedImage(8, 8); + int[] bgcolor = new int[1]; + img.getRGB(0, 0, 1, 1, bgcolor, 0, 1); /* Get BG color (for accessory face) */ img.getRGB(8, 8, 8, 8, face8x8.argb_buf, 0, 8); /* Read face from image */ img.getRGB(40, 8, 8, 8, faceaccessory, 0, 8); /* Read face accessory from image */ /* Apply accessory to face: first element is transparency color so only ones not matching it */ for(int i = 0; i < 64; i++) { - if(faceaccessory[i] != faceaccessory[0]) + if(faceaccessory[i] != bgcolor[0]) face8x8.argb_buf[i] = faceaccessory[i]; + else if(face8x8.argb_buf[i] == bgcolor[0]) + face8x8.argb_buf[i] = 0; } /* Write 8x8 file */ File img_8x8 = new File(faces8x8dir, playername + ".png"); From 04cc6aba4333b1a2f514bdfd99de9b6f08fe5dd1 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Thu, 25 Aug 2011 11:11:31 +0800 Subject: [PATCH 2/6] Towny fixes - multiple areas on multiple worlds per town --- .../dynmap/regions/TownyConfigHandler.java | 227 +++++++++++------- web/js/regions.js | 30 +-- web/js/regions_Towny.js | 31 +-- 3 files changed, 170 insertions(+), 118 deletions(-) diff --git a/src/main/java/org/dynmap/regions/TownyConfigHandler.java b/src/main/java/org/dynmap/regions/TownyConfigHandler.java index 5f4865d8..d5aab6f5 100644 --- a/src/main/java/org/dynmap/regions/TownyConfigHandler.java +++ b/src/main/java/org/dynmap/regions/TownyConfigHandler.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; @@ -61,6 +62,23 @@ public class TownyConfigHandler { private static final String FLAGS[] = { "hasUpkeep", "pvp", "mobs", "public", "explosion", "fire" }; + + /** + * Find all contiguous blocks, set in target and clear in source + */ + private int floodFillTarget(TileFlags src, TileFlags dest, int x, int y) { + int cnt = 0; + if(src.getFlag(x, y)) { /* Set in src */ + src.setFlag(x, y, false); /* Clear source */ + dest.setFlag(x, y, true); /* Set in destination */ + cnt++; + cnt += floodFillTarget(src, dest, x+1, y); /* Fill adjacent blocks */ + cnt += floodFillTarget(src, dest, x-1, y); + cnt += floodFillTarget(src, dest, x, y+1); + cnt += floodFillTarget(src, dest, x, y-1); + } + return cnt; + } /** * Process data from given town file */ @@ -80,113 +98,152 @@ public class TownyConfigHandler { } /* Get block list */ String blocks = p.getProperty("townBlocks"); - /* If it doesn't start with world, we're done (town on different world) */ - if((blocks == null) || (!blocks.startsWith(wname+":"))) - return null; String[] nodes = blocks.split(";"); /* Split into list */ TileFlags blks = new TileFlags(); - ArrayList nodevals = new ArrayList(); - int minx = Integer.MAX_VALUE; - int miny = Integer.MAX_VALUE; + LinkedList nodevals = new LinkedList(); + boolean worldmatch = false; + for(String n: nodes) { + /* Is world prefix? */ int idx = n.indexOf(':'); - if(idx >= 0) n = n.substring(idx+1); + if(idx >= 0) { + String w = n.substring(0, idx); + if(w.startsWith("|")) w = w.substring(1); + worldmatch = w.equals(wname); /* See if our world */ + n = n.substring(idx+1); /* Process remainder as coordinate */ + } + if(!worldmatch) continue; String[] v = n.split(","); if(v.length == 2) { try { int[] vv = new int[] { Integer.valueOf(v[0]), Integer.valueOf(v[1]) }; blks.setFlag(vv[0], vv[1], true); nodevals.add(vv); - if(vv[0] < minx) { - minx = vv[0]; - miny = vv[1]; - } - else if((vv[0] == minx) && (vv[1] < miny)) { - miny = vv[1]; - } } catch (NumberFormatException nfx) { Log.severe("Error parsing block list in Towny - " + townfile.getPath()); return null; } } } - /* Trace outline of blocks - start from minx, miny going to x+ */ - int init_x = minx; - int init_y = miny; - int cur_x = minx+1; - int cur_y = miny; - direction dir = direction.XPLUS; - ArrayList linelist = new ArrayList(); - linelist.add(new int[] { init_x, init_y } ); // Add start point - while((cur_x != init_x) || (cur_y != init_y)) { - switch(dir) { - case XPLUS: /* Segment in X+ direction */ - if(!blks.getFlag(cur_x+1, cur_y)) { /* Right turn? */ - linelist.add(new int[] { cur_x+1, cur_y }); /* Finish line */ - dir = direction.YPLUS; /* Change direction */ + /* If nothing in this world, skip */ + if(nodevals.size() == 0) + return null; + /* Loop through until we don't find more areas */ + ArrayList[]> polygons = new ArrayList[]>(); + while(nodevals != null) { + LinkedList ournodes = null; + LinkedList newlist = null; + TileFlags ourblks = null; + int minx = Integer.MAX_VALUE; + int miny = Integer.MAX_VALUE; + for(int[] node : nodevals) { + if((ourblks == null) && blks.getFlag(node[0], node[1])) { /* Node still in map? */ + ourblks = new TileFlags(); /* Create map for shape */ + ournodes = new LinkedList(); + floodFillTarget(blks, ourblks, node[0], node[1]); /* Copy shape */ + ournodes.add(node); /* Add it to our node list */ + minx = node[0]; miny = node[1]; + } + /* If shape found, and we're in it, add to our node list */ + else if((ourblks != null) && (ourblks.getFlag(node[0], node[1]))) { + ournodes.add(node); + if(node[0] < minx) { + minx = node[0]; miny = node[1]; } - else if(!blks.getFlag(cur_x+1, cur_y-1)) { /* Straight? */ - cur_x++; + else if((node[0] == minx) && (node[1] < miny)) { + miny = node[1]; } - else { /* Left turn */ - linelist.add(new int[] { cur_x+1, cur_y }); /* Finish line */ - dir = direction.YMINUS; - cur_x++; cur_y--; - } - break; - case YPLUS: /* Segment in Y+ direction */ - if(!blks.getFlag(cur_x, cur_y+1)) { /* Right turn? */ - linelist.add(new int[] { cur_x+1, cur_y+1 }); /* Finish line */ - dir = direction.XMINUS; /* Change direction */ - } - else if(!blks.getFlag(cur_x+1, cur_y+1)) { /* Straight? */ - cur_y++; - } - else { /* Left turn */ - linelist.add(new int[] { cur_x+1, cur_y+1 }); /* Finish line */ - dir = direction.XPLUS; - cur_x++; cur_y++; - } - break; - case XMINUS: /* Segment in X- direction */ - if(!blks.getFlag(cur_x-1, cur_y)) { /* Right turn? */ - linelist.add(new int[] { cur_x, cur_y+1 }); /* Finish line */ - dir = direction.YMINUS; /* Change direction */ - } - else if(!blks.getFlag(cur_x-1, cur_y+1)) { /* Straight? */ - cur_x--; - } - else { /* Left turn */ - linelist.add(new int[] { cur_x, cur_y+1 }); /* Finish line */ - dir = direction.YPLUS; - cur_x--; cur_y++; - } - break; - case YMINUS: /* Segment in Y- direction */ - if(!blks.getFlag(cur_x, cur_y-1)) { /* Right turn? */ - linelist.add(new int[] { cur_x, cur_y }); /* Finish line */ - dir = direction.XPLUS; /* Change direction */ - } - else if(!blks.getFlag(cur_x-1, cur_y-1)) { /* Straight? */ - cur_y--; - } - else { /* Left turn */ - linelist.add(new int[] { cur_x, cur_y }); /* Finish line */ - dir = direction.XMINUS; - cur_x--; cur_y--; - } - break; + } + else { /* Else, keep it in the list for the next polygon */ + if(newlist == null) newlist = new LinkedList(); + newlist.add(node); + } } + nodevals = newlist; /* Replace list (null if no more to process) */ + if(ourblks == null) continue; /* Nothing found, skip to end */ + /* Trace outline of blocks - start from minx, miny going to x+ */ + int init_x = minx; + int init_y = miny; + int cur_x = minx; + int cur_y = miny; + direction dir = direction.XPLUS; + ArrayList linelist = new ArrayList(); + linelist.add(new int[] { init_x, init_y } ); // Add start point + while((cur_x != init_x) || (cur_y != init_y) || (dir != direction.YMINUS)) { + switch(dir) { + case XPLUS: /* Segment in X+ direction */ + if(!ourblks.getFlag(cur_x+1, cur_y)) { /* Right turn? */ + linelist.add(new int[] { cur_x+1, cur_y }); /* Finish line */ + dir = direction.YPLUS; /* Change direction */ + } + else if(!ourblks.getFlag(cur_x+1, cur_y-1)) { /* Straight? */ + cur_x++; + } + else { /* Left turn */ + linelist.add(new int[] { cur_x+1, cur_y }); /* Finish line */ + dir = direction.YMINUS; + cur_x++; cur_y--; + } + break; + case YPLUS: /* Segment in Y+ direction */ + if(!ourblks.getFlag(cur_x, cur_y+1)) { /* Right turn? */ + linelist.add(new int[] { cur_x+1, cur_y+1 }); /* Finish line */ + dir = direction.XMINUS; /* Change direction */ + } + else if(!ourblks.getFlag(cur_x+1, cur_y+1)) { /* Straight? */ + cur_y++; + } + else { /* Left turn */ + linelist.add(new int[] { cur_x+1, cur_y+1 }); /* Finish line */ + dir = direction.XPLUS; + cur_x++; cur_y++; + } + break; + case XMINUS: /* Segment in X- direction */ + if(!ourblks.getFlag(cur_x-1, cur_y)) { /* Right turn? */ + linelist.add(new int[] { cur_x, cur_y+1 }); /* Finish line */ + dir = direction.YMINUS; /* Change direction */ + } + else if(!ourblks.getFlag(cur_x-1, cur_y+1)) { /* Straight? */ + cur_x--; + } + else { /* Left turn */ + linelist.add(new int[] { cur_x, cur_y+1 }); /* Finish line */ + dir = direction.YPLUS; + cur_x--; cur_y++; + } + break; + case YMINUS: /* Segment in Y- direction */ + if(!ourblks.getFlag(cur_x, cur_y-1)) { /* Right turn? */ + linelist.add(new int[] { cur_x, cur_y }); /* Finish line */ + dir = direction.XPLUS; /* Change direction */ + } + else if(!ourblks.getFlag(cur_x-1, cur_y-1)) { /* Straight? */ + cur_y--; + } + else { /* Left turn */ + linelist.add(new int[] { cur_x, cur_y }); /* Finish line */ + dir = direction.XMINUS; + cur_x--; cur_y--; + } + break; + } + } + @SuppressWarnings("unchecked") + Map[] coordlist = new Map[linelist.size()]; + for(int i = 0; i < linelist.size(); i++) { + coordlist[i] = new HashMap(); + coordlist[i].put("x", linelist.get(i)[0] * townblocksize); + coordlist[i].put("z", linelist.get(i)[1] * townblocksize); + } + polygons.add(coordlist); } @SuppressWarnings("unchecked") - Map[] coordlist = new Map[linelist.size()]; - for(int i = 0; i < linelist.size(); i++) { - coordlist[i] = new HashMap(); - coordlist[i].put("x", linelist.get(i)[0] * townblocksize); - coordlist[i].put("z", linelist.get(i)[1] * townblocksize); - } + Map[][] polylist = new Map[polygons.size()][]; + polygons.toArray(polylist); rslt = new HashMap(); - rslt.put("points", coordlist); + rslt.put("points", polylist); + /* Add other data */ String mayor = p.getProperty("mayor"); if(mayor != null) rslt.put("mayor", mayor); diff --git a/web/js/regions.js b/web/js/regions.js index 716b4de8..9170f97d 100644 --- a/web/js/regions.js +++ b/web/js/regions.js @@ -53,44 +53,38 @@ componentconstructors['regions'] = function(dynmap, configuration) { } function create3DBoxLayer(maxx, minx, maxy, miny, maxz, minz, style) { - return new L.FeatureGroup([ - new L.Polygon([ + return new L.MultiPolygon([ + [ latlng(minx,miny,minz), latlng(maxx,miny,minz), latlng(maxx,miny,maxz), latlng(minx,miny,maxz) - ], style), - new L.Polygon([ + ],[ latlng(minx,maxy,minz), latlng(maxx,maxy,minz), latlng(maxx,maxy,maxz), latlng(minx,maxy,maxz) - ], style), - new L.Polygon([ + ],[ latlng(minx,miny,minz), latlng(minx,maxy,minz), latlng(maxx,maxy,minz), latlng(maxx,miny,minz) - ], style), - new L.Polygon([ + ],[ latlng(maxx,miny,minz), latlng(maxx,maxy,minz), latlng(maxx,maxy,maxz), latlng(maxx,miny,maxz) - ], style), - new L.Polygon([ + ],[ latlng(minx,miny,maxz), latlng(minx,maxy,maxz), latlng(maxx,maxy,maxz), latlng(maxx,miny,maxz) - ], style), - new L.Polygon([ + ],[ latlng(minx,miny,minz), latlng(minx,maxy,minz), latlng(minx,maxy,maxz), latlng(minx,miny,maxz) - ], style) - ]); + ]], style); } function create2DBoxLayer(maxx, minx, maxy, miny, maxz, minz, style) { @@ -117,12 +111,12 @@ componentconstructors['regions'] = function(dynmap, configuration) { sidelist[1] = botlist[i]; sidelist[2] = botlist[(i+1)%xarray.length]; sidelist[3] = toplist[(i+1)%xarray.length]; - polylist[i] = new L.Polygon(sidelist, style); + polylist[i] = sidelist; } - polylist[xarray.length] = new L.Polygon(botlist, style); - polylist[xarray.length+1] = new L.Polygon(toplist, style); + polylist[xarray.length] = botlist; + polylist[xarray.length+1] = toplist; - return new L.FeatureGroup(polylist); + return new L.MultiPolygon(polylist, style); } function create2DOutlineLayer(xarray, maxy, miny, zarray, style) { diff --git a/web/js/regions_Towny.js b/web/js/regions_Towny.js index ea3a5357..641dc116 100644 --- a/web/js/regions_Towny.js +++ b/web/js/regions_Towny.js @@ -1,14 +1,12 @@ regionConstructors['Towny'] = function(dynmap, configuration) { // Helper function. - function createOutlineFromRegion(name, region, outCreator) { + function createOutlineFromRegion(name, region, points, outCreator) { var xarray = []; var zarray = []; - if(region.points) { - var i; - for(i = 0; i < region.points.length; i++) { - xarray[i] = region.points[i].x; - zarray[i] = region.points[i].z; - } + var i; + for(i = 0; i < points.length; i++) { + xarray[i] = points[i].x; + zarray[i] = points[i].z; } var ymin = 64; var ymax = 65; @@ -20,14 +18,17 @@ regionConstructors['Towny'] = function(dynmap, configuration) { $.getJSON('standalone/'+regionFile, function(data) { var boxLayers = []; $.each(data, function(name, region) { - var outLayer = createOutlineFromRegion(name, region, configuration.createOutlineLayer); - if (outLayer) { - outLayer.bindPopup(configuration.createPopupContent(name, - $.extend(region, { - owners: { players: [region.mayor] }, - members: { players: [ region.residents ] } - }))); - boxLayers.push(outLayer); + var i; + for(i = 0; i < region.points.length; i++) { + var outLayer = createOutlineFromRegion(name, region, region.points[i], configuration.createOutlineLayer); + if (outLayer) { + outLayer.bindPopup(configuration.createPopupContent(name, + $.extend(region, { + owners: { players: [region.mayor] }, + members: { players: [ region.residents ] } + }))); + boxLayers.push(outLayer); + } } }); configuration.result(new L.LayerGroup(boxLayers)); From 316440a4e0fe5c698de879ebd98f442e22393db6 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Fri, 26 Aug 2011 03:48:42 +0800 Subject: [PATCH 3/6] Disable IOImage cache use for image loads --- src/main/java/org/dynmap/hdmap/TexturePack.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/dynmap/hdmap/TexturePack.java b/src/main/java/org/dynmap/hdmap/TexturePack.java index 63f7953c..d87c4230 100644 --- a/src/main/java/org/dynmap/hdmap/TexturePack.java +++ b/src/main/java/org/dynmap/hdmap/TexturePack.java @@ -369,6 +369,7 @@ public class TexturePack { private void loadTerrainPNG(InputStream is) throws IOException { int i, j; /* Load image */ + ImageIO.setUseCache(false); BufferedImage img = ImageIO.read(is); if(img == null) { throw new FileNotFoundException(); } terrain_width = img.getWidth(); @@ -429,6 +430,7 @@ public class TexturePack { /* Load image into image array */ private void loadImage(InputStream is, int idx) throws IOException { /* Load image */ + ImageIO.setUseCache(false); BufferedImage img = ImageIO.read(is); if(img == null) { throw new FileNotFoundException(); } imgs[idx] = new LoadedImage(); @@ -642,6 +644,7 @@ public class TexturePack { } } BufferedImage img = DynmapBufferedImage.createBufferedImage(outbuf, terrain_width, terrain_height); + ImageIO.setUseCache(false); ImageIO.write(img, "png", f); } From d9ad51edd68b19567f20e2d8144110c95849ec77 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Fri, 26 Aug 2011 03:49:32 +0800 Subject: [PATCH 4/6] Use towns list in Towny worlds/* files to get valid towns (old towns still in towns/* directory) --- .../dynmap/regions/TownyConfigHandler.java | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/dynmap/regions/TownyConfigHandler.java b/src/main/java/org/dynmap/regions/TownyConfigHandler.java index d5aab6f5..27813891 100644 --- a/src/main/java/org/dynmap/regions/TownyConfigHandler.java +++ b/src/main/java/org/dynmap/regions/TownyConfigHandler.java @@ -39,19 +39,30 @@ public class TownyConfigHandler { */ public Map getRegionData(String wname) { Map rslt = new HashMap(); - /* List towns directory - process all towns there */ - File towndir = new File("plugins/Towny/data/towns"); - File[] towns = towndir.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.endsWith(".txt"); + Properties p = new Properties(); + FileInputStream fis = null; + /* Read world data for this world */ + try { + fis = new FileInputStream("plugins/Towny/data/worlds/" + wname + ".txt"); /* Open and load file */ + p.load(fis); + } catch (IOException iox) { + Log.severe("Error loading Towny world file " + wname + ".txt"); + } finally { + if(fis != null) { + try { fis.close(); } catch (IOException iox) {} } - }); - for(File town : towns) { - Map td = processTown(town, wname); + } + /* Get towns list for our world */ + String t = p.getProperty("towns", ""); + String towns[] = t.split(","); /* Split on commas */ + /* List towns directory - process all towns there */ + for(String town : towns) { + town = town.trim(); + if(town.length() == 0) continue; + File tfile = new File("plugins/Towny/data/towns/" + town + ".txt"); + Map td = processTown(tfile, wname); if(td != null) { - String fn = town.getName(); - rslt.put(fn.substring(0, fn.lastIndexOf('.')), td); + rslt.put(town, td); } } return rslt; From 59b095628d6e7a8d182ff91a94cbcfc6a0a549b7 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Fri, 26 Aug 2011 06:07:00 +0800 Subject: [PATCH 5/6] Add control for hide/show of component layers (only regions for now) --- web/js/dynmaputils.js | 6 ++++++ web/js/map.js | 8 +++++++- web/js/regions.js | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/web/js/dynmaputils.js b/web/js/dynmaputils.js index 14304afd..e4dfb893 100644 --- a/web/js/dynmaputils.js +++ b/web/js/dynmaputils.js @@ -43,6 +43,12 @@ if (!Array.prototype.indexOf) { } } +var DynmapLayerControl = L.Control.Layers.extend({ + getPosition: function() { + return L.Control.Position.TOP_LEFT; + } +}); + var DynmapTileLayer = L.TileLayer.extend({ _currentzoom: undefined, diff --git a/web/js/map.js b/web/js/map.js index 5f4e73b8..c558880e 100644 --- a/web/js/map.js +++ b/web/js/map.js @@ -41,6 +41,7 @@ DynMap.prototype = { inittime: new Date().getTime(), followingPlayer: '', missedupdates: 0, + layercontrol: undefined, formatUrl: function(name, options) { var url = this.options.url[name]; $.each(options, function(n,v) { @@ -137,6 +138,9 @@ DynMap.prototype = { me.followPlayer(null); });*/ + me.layercontrol = new DynmapLayerControl(); + map.addControl(me.layercontrol); + // Sidebar var panel; var sidebar; @@ -319,7 +323,8 @@ DynMap.prototype = { var prevzoom = me.map.getZoom(); if (me.maptype) { - me.map.removeLayer(me.maptype); + me.layercontrol.removeLayer(me.maptype); + //me.map.removeLayer(me.maptype); } var prevmap = me.maptype; @@ -356,6 +361,7 @@ DynMap.prototype = { me.map.setZoom(prevzoom); } me.map.addLayer(me.maptype); + //me.layercontrol.addBaseLayer(me.maptype, 'Tiles'); if (worldChanged) { $(me).trigger('worldchanged'); diff --git a/web/js/regions.js b/web/js/regions.js index 9170f97d..e3ea82fe 100644 --- a/web/js/regions.js +++ b/web/js/regions.js @@ -165,6 +165,7 @@ componentconstructors['regions'] = function(dynmap, configuration) { var activeLayer = undefined; function undraw() { if (activeLayer) { + dynmap.layercontrol.removeLayer(activeLayer); dynmap.map.removeLayer(activeLayer); activeLayer = undefined; } @@ -183,6 +184,7 @@ componentconstructors['regions'] = function(dynmap, configuration) { result: function(regionsLayer) { activeLayer = regionsLayer; dynmap.map.addLayer(activeLayer); + dynmap.layercontrol.addOverlay(activeLayer, regionType); } })); } From 106e470898f3170673fedb61713e059f30527a07 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Fri, 26 Aug 2011 06:31:34 +0800 Subject: [PATCH 6/6] Add playermarkers to hide/show-able layer group --- web/js/playermarkers.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/web/js/playermarkers.js b/web/js/playermarkers.js index fd621276..60268547 100644 --- a/web/js/playermarkers.js +++ b/web/js/playermarkers.js @@ -72,18 +72,18 @@ componentconstructors['playermarkers'] = function(dynmap, configuration) { return div; }}); if(dynmap.world === player.location.world) - dynmap.map.addLayer(player.marker); + dynmap.playermarkergroup.addLayer(player.marker); }); $(dynmap).bind('playerremoved', function(event, player) { // Remove the marker. if(dynmap.map.hasLayer(player.marker)) - dynmap.map.removeLayer(player.marker); + dynmap.playermarkergroup.removeLayer(player.marker); }); $(dynmap).bind('playerupdated', function(event, player) { if(dynmap.world === player.location.world) { // Add if needed if(dynmap.map.hasLayer(player.marker) == false) - dynmap.map.addLayer(player.marker); + dynmap.playermarkergroup.addLayer(player.marker); else { // Update the marker. var markerPosition = dynmap.getProjection().fromLocationToLatLng(player.location); @@ -100,7 +100,7 @@ componentconstructors['playermarkers'] = function(dynmap, configuration) { } } } else if(dynmap.map.hasLayer(player.marker)) { - dynmap.map.removeLayer(player.marker); + dynmap.playermarkergroup.removeLayer(player.marker); } }); // Remove marker on start of map change @@ -109,7 +109,7 @@ componentconstructors['playermarkers'] = function(dynmap, configuration) { for(name in dynmap.players) { var player = dynmap.players[name]; // Turn off marker - let update turn it back on - dynmap.map.removeLayer(player.marker); + dynmap.playermarkergroup.removeLayer(player.marker); } }); // Remove marker on map change - let update place it again @@ -119,12 +119,15 @@ componentconstructors['playermarkers'] = function(dynmap, configuration) { var player = dynmap.players[name]; if(dynmap.world === player.location.world) { if(dynmap.map.hasLayer(player.marker) == false) - dynmap.map.addLayer(player.marker); + dynmap.playermarkergroup.addLayer(player.marker); var markerPosition = dynmap.getProjection().fromLocationToLatLng(player.location); player.marker.setLatLng(markerPosition); } else if(dynmap.map.hasLayer(player.marker)) { - dynmap.map.removeLayer(player.marker); + dynmap.playermarkergroup.removeLayer(player.marker); } } }); + dynmap.playermarkergroup = new L.LayerGroup(); + dynmap.map.addLayer(dynmap.playermarkergroup); + dynmap.layercontrol.addOverlay(dynmap.playermarkergroup, 'Players'); };