Map API issues

Discussion in 'Plugin Development' started by dkramer, Oct 23, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    dkramer

    For my plugin in the works, MineConquer, maps act as "minimaps", with you in the center and the world moving around you. I have a problem where it will not render correctly if two people are using the same map ID, but will work if it's rendering only on one person's. Here's shortened versions of some classes:

    Main class:

    Code:
    public class Main extends JavaPlugin{
    
        public static int MAP_SECOND_DELAY;
    
        private MapListener mapListener = new MapListener();
    
        public void onEnable() {
            MAP_SECOND_DELAY = config.getInt("customize.mapSecondDelay", 3);
            config.save();
    
            MapRend.applyToMap(getServer().getMap((short) 0));
    
            PluginManager pm = getServer().getPluginManager();
            pm.registerEvent(Event.Type.MAP_INITIALIZE, this.mapListener, Event.Priority.Normal, this);
    
        }
    }
    Listener:

    Code:
    public class MapListener extends ServerListener {
        @Override
        public void onMapInitialize(MapInitializeEvent event) {
            MapRend.applyToMap(event.getMap());
        }
    }
    Renderer:
    Code:
    package me.dalton.mineconquer.Map;
    
    import java.util.HashMap;
    import java.util.List;
    
    import me.dalton.mineconquer.ChunkData;
    import me.dalton.mineconquer.GamePlayer;
    import me.dalton.mineconquer.Globals;
    import me.dalton.mineconquer.Util;
    
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.map.MapCanvas;
    import org.bukkit.map.MapPalette;
    import org.bukkit.map.MapRenderer;
    import org.bukkit.map.MapView;
    
    public class MapRend extends MapRenderer {
        private MapCanvas canvas;
        private int renderIndex = 0;
        private int pChunkX, pChunkZ;
        private boolean[][] bools;
        private static HashMap<Player , boolean[][]> modified = new HashMap<Player , boolean[][]>();
        private static HashMap<Player , ChunkData> pLocations = new HashMap<Player , ChunkData>();
    
        public MapRend(){
            super(true);
        }
    
        @Override
        public void render(MapView map, MapCanvas canvas, Player player) {
    
            renderIndex++;
            if (renderIndex % Globals.MAP_SECOND_DELAY * 20 != 0) return;
            renderIndex = 0;
    
            if (player.getItemInHand().getType() != Material.MAP)
                return;
    
            if (player.getItemInHand().getDurability() != 0)
                return;
    
            ChunkData pChunk = new ChunkData(player.getLocation().getBlock().getChunk());
            if(pLocations.containsKey(player) && pChunk.equals(pLocations.get(player)))
                return;
    
            this.canvas = canvas;
    
            if(!modified.containsKey(player))
                modified.put(player, new boolean[128][128]);
    
            boolean[][] playerBools = modified.get(player);
            for(int x=0; x<128; x++)
                for(int z=0; z<128; z++)
                    if(playerBools[x][z] == true)
                        this.canvas.setPixel(x, z, MapPalette.TRANSPARENT);
    
            bools = new boolean[128][128];
    
            pChunkX = pChunk.X;
            pChunkZ = pChunk.Z;
    
            GamePlayer gP = GamePlayer.get(player.getName());
            listIterate(Util.unclaimedChunks , MapPalette.GRAY_1);
            listIterate(gP.getEnemyChunks() , MapPalette.RED);
            listIterate(gP.getAllyChunks() , MapPalette.LIGHT_GREEN);
            listIterate(gP.chunks, MapPalette.DARK_GREEN);
    
            setCanvasSquare(MapPalette.BLUE , 65 , 65 , 2);
    
            pLocations.put(player, pChunk);
            modified.put(player, bools);
        }
    
        public void listIterate(List<ChunkData> list , byte color){
            for(ChunkData chunk : list){
                int distX = pChunkX - chunk.X;
                int distZ = pChunkZ - chunk.Z;
    
                if (Math.abs(distX) < 16 && Math.abs(distZ) < 16)
                    setCanvasSquare(color , distX * 4 + 64 , distZ * 4 + 64 , 4);
            }
        }
    
        public void setCanvasSquare(byte color , int x , int z , int size){
            for(int t = x; t < x + size; t++)
                for(int ta = z; ta < z + size; ta++){
                    if((t == x || t == x + size-1) || (ta == z || ta == z + size-1)){
                        this.canvas.setPixel(t , ta, color);
                        bools[t][ta] = true;
                    }
                }
        }
    
        public static void applyToMap(MapView map) {
            if(map != null){
                for (MapRenderer renderer : map.getRenderers())
                    map.removeRenderer(renderer);
                map.addRenderer(new MapRend());
            }
        }
    }
     
    dadaemon likes this.
  2. As far as I know maps are rendered by map ID. So if player1 and player2 has the same map they both get to see the same thing. So it's best to check if a map isn't viewed by another person first.
     
  3. Offline

    desht

    Yes, but the call to "super(true)" in the MapRend constructor should ensure a contextual MapRenderer is created, i.e. a separate canvas for each player. I can't see any problems in the code myself - maybe something for @SpaceManiac or @codename_B to comment on? They're the Map API experts :)
     
  4. Offline

    codename_B

    I'm not so great with seperate canvas for each player (Yet) I haven't messed with the map api in aaaaaaaaaages.
     
  5. Offline

    dralletje

    there is no error if two people use maps with different ID's at the same time?
    cause there is 1 maplistener with global variables.
    maybe if you make all global variables local for the function?
    of create a renderer object for every player/map?
     
  6. I forget the exact function, but there's a context option somewhere in the map API to make it per player.
     
  7. Offline

    dkramer

    Alright, thanks guys, I'll see if I can solve it.
     
  8. Ok, my knowledge of the MAP api is just crap I see. :p

    If you have this working, could you please add the solution here?
     
  9. Offline

    dkramer

    I changed around a bit of the renderer code, and it seems to be working now (I edited the OP to the updated code). I'll do more testing later though to see if it is actually working as it should be.
     
  10. I've been working on my addon and the use of maps and your code was excactly what I needed to make it work for all players watching the same map (id.)

    Many thanks @dkramer ! This should be in the resource section!
     
Thread Status:
Not open for further replies.

Share This Page