Solved getting all enderchests in a world

Discussion in 'Spigot Plugin Development' started by mlgcraftnetwork, May 27, 2016.

  1. So what I want to do is find all enderchest block locations in a specific world but I can't figure out how to do it. I think you should use something like:
    Code (Text):
        public void holoLoad(World world) {
            for(Block b : world.getBlocks(Material.ENDER_CHEST){
             
            }
        }
    But could anyone explain me how to get this to work? Thanks.
     
  2. Something like that wont work. You have to loop through all blocks of the area where want to search for ender chests, or you can save the locations on block place in a config file.
     
  3. Aren't enderchests treated like entities since they store data, hence they should be located in the World's entity list... loop through that instead

    -- Edit --

    Use this and check if the instance is an enderchest

    Code (Text):
        @EventHandler
        public void onChunkLoad(ChunkLoadEvent e) {
            for (BlockState tile : e.getChunk().getTileEntities()) {
                if (tile instanceof EnderChest) {
                    System.out.println("Enderchest detected at " + tile.getLocation());
                     //Insert code here
                }
            }
        }
     
  4. I don't believe so, I'm fairly certain they are stored as a block because if you place a chest/enderchest with custom data like names, lore, etc, they don't keep that data when you break and pick them back up. They also don't respond to any kind of physics which, I think, makes them blocks, not entities.
     
  5. A tile entity is just a block that has a 'Block Entity' object linked to it. The physical thing a player sees in game though is a block, not an entity.

    The "entity" part of the enderchest is not something that anything can interact with, it is just an "invisible" object linked to the chest to store data using the Entity class that was already made.
     
    • Agree Agree x 1
    • Informative Informative x 1
  6. @Hunky524 I agree, but I'm 99% sure you can use the TileEntity object to get the Block which the Entity is associated with. The OP wants to get all the enderchests in his world. So first, you loop through the loaded chunks in the world, then you loop through the entities in the world. You check if the entity is an instance of an Enderchest, then you save that Enderchest's block and do whatever you want to do with it
     
    • Agree Agree x 2
  7. This didn't work, did I do anything wrong?

    Code:
    Code (Text):
        @EventHandler
        public void onChunkLoad(ChunkLoadEvent e) {
            for (BlockState ender : e.getChunk().getTileEntities()) {
                if (ender instanceof EnderChest) {
                    Location bloc = ender.getLocation();
                    bloc.setY(bloc.getY() -2);
                    @SuppressWarnings("deprecation")
                    int block = bloc.getWorld().getBlockTypeIdAt(bloc);
                    if (block == 152) {
                        Location hdloc = ender.getLocation();
                        hdloc.setY(hdloc.getY() -0.6);
                        hdloc.setX(hdloc.getX() + 0.5);
                        hdloc.setZ(hdloc.getZ() + 0.5);
                        Location hdloc2 = ender.getLocation();
                        hdloc2.setY(hdloc2.getY() -0.8);
                        hdloc2.setX(hdloc2.getX() + 0.5);
                        hdloc2.setZ(hdloc2.getZ() + 0.5);
                        Main.api.spawnHolo(hdloc, "§e§lDAILYREWARD");
                        Main.api.spawnHolo(hdloc2, "§7(Right-Click)");
                    }
                }
            }
        }
     
  8. Just to clear a few things up:
    A BlockEntity is NO Entity. Both are completely different concepts:
    An Entity is a thing that has a position that can change. It moves through the world (mostly, except things like Paintings) and two Entities can occupy the same space. Also, Entites can change chunks.
    Entites may have additional data saved in an NBTTag.


    A BlockEntity (also called TileEntity because thats what mojang calls it) is just a class that provides additional data to a block. A chest (all blocks with an Inventory) use this to store it contents. It cannot move and is bound to a block. Also, two cannot occupy the same space.
    It also may have additional data saved in an NBTTag.

    PS: Please note that a piston is no entity. It's a block with a TileEntity pretending to be another block while the Piston extends, which is rendered to "move".
     
  9. What exactly is not working? Pay attention that you assign ender.getLocation() to hdloc and modify it, you then assign ender.getLocation() to hdloc2 and modify it again. By modifying hdloc you've modified ender.getLocation() ... if that makes sense. This might not be what you intended to do.
     
  10. Really? oh I will take a look at that, thanks.
     
  11. Sorry for the late responds, no my console didn't give me any errors and what I meant with "is not working" is that its not spawning my holograms.
     
  12. I am just a little bit confused by your code so let me see if I have this correct.
    You first get all tile entites in the chunk, iterate through them, and check if they are enderchests.
    If it is an enderchest you then check if the block 2 blocks below is a redstone block, and then you modify the position again and spawn the hologram.

    I am not sure if this is what you intended, but I can tell you right now your hologram is
    being spawned underground. :p Assuming there is ground below the enderchest that is and of course the redstone block 2 blocks below it.
     
    #14 NinjaStix, May 29, 2016
    Last edited: May 29, 2016
  13. I changed my code after you said I was modifying the ender loc so this it what I have right now:
    Code (Text):
        @EventHandler
        public void onChunkLoad(ChunkLoadEvent e) {
            for (BlockState ender : e.getChunk().getTileEntities()) {
                if (ender instanceof EnderChest) {
                    Location bloc = ender.getLocation();
                    bloc.setY(bloc.getY() -2);
                    @SuppressWarnings("deprecation")
                    int block = bloc.getWorld().getBlockTypeIdAt(bloc);
                    if (block == 152) {
                        World w = ender.getLocation().getWorld();
                        int x = ender.getLocation().getBlockX();
                        int y = ender.getLocation().getBlockY();
                        int z = ender.getLocation().getBlockZ();
                        Location hdloc = new Location(w, x + 0.5, y + -0.7, z + 0.5);
                        Location hdloc2 = new Location(w, x + 0.5, y + -1, z + 0.5);
                        Main.api.spawnHolo(hdloc, "§e§lDAILYREWARD");
                        Main.api.spawnHolo(hdloc2, "§7(Right-Click)");
                    }
                }
            }
        }
    Basicly what I want is:
    - get all enderchests in "World"
    - if the block 2 blocks below the chest is a redstone block then add a hologram above the chest.
     
  14. This should work(cleaned it up a bit):
    Code (Text):

    @EventHandler
    public void onChunkLoad(ChunkLoadEvent e) {
        for (BlockState ender : e.getChunk().getTileEntities()) {
            if (ender.getType() == Material.ENDER_CHEST) {
                Location bloc = ender.getLocation();
                World w = bloc.getWorld();
                int x = bloc.getBlockX();
                int y = bloc.getBlockY();
                int z = bloc.getBlockZ();
                Block below = bloc.getWorld().getBlockAt(bloc.getBlockX(), bloc.getBlockY() - 2, bloc.getBlockZ());
                if (below.getType() == Material.REDSTONE_BLOCK) {
                    Location hdloc = new Location(w, x + 0.5D, y + 1D, z + 0.5D);
                    Location hdloc2 = new Location(w, x + 0.5D, y + 0.7D, z + 0.5D);
                    Main.api.spawnHolo(hdloc, "§e§lDAILYREWARD");
                    Main.api.spawnHolo(hdloc2, "§7(Right-Click)");
                }
            }
        }
    }
     
    If not try spawning a hologram at your location to ensure they are indeed spawning.
     
  15. This didn't do the trick but I'm sure my hologram spawning code works. Just to be sure, the loadChunk event is fired when restarting the server right? Is there any way we can run this code on enable?
     
  16. Is this world already created or are you going to create it? If you're going to create it, then just listen for block place events as enderchests aren't naturally generated.
     
    • Agree Agree x 1
  17. Yes, I would probably do something like this as well. You can then store the locations of the holograms in a flat file or something and load them on startup.

    In your code your setting all holograms to this text
    Code (Text):

    Main.api.spawnHolo(hdloc, "§e§lDAILYREWARD");
    Main.api.spawnHolo(hdloc2, "§7(Right-Click)");
     
    If this is all the code is for I suggest doing this via command, and place them based on your location.
     
  18. The world has already been generated, but I want to (re-)spawn the holograms onEnable() because I made it so all holograms are removed onDisable(). Is there really no way to get all enderchests in a world? Because I know there are plugins that scan the world for chests and fill them with loot.