[Solved] Getting nearest chest to player

Discussion in 'Spigot Plugin Development' started by TimeVisualSales, May 24, 2015.

Thread Status:
Not open for further replies.
  1. Hi there, is it possible to get the nearest chest to the player in a block radius of 5 blocks and store certain items in it? If it is, how would I do it?
     
  2. Iterate in a for loop through locations around player and break if block equals chest?
    Or if multiple chests found, add to list then compare location distance and use the minimum. Not sure how server intensive that could be.
     
  3. How would I do this? Sorry, I cant think today as I'm ill.
     
    • Funny Funny x 1
  4. this is the method to get chest in a radius:
    public Location circle(Location loc, int radius){
    int cx = loc.getBlockX();
    int cy = loc.getBlockY();
    int cz = loc.getBlockZ();

    for(int x = cx - radius; x <= cx + radius; x++){
    for (int z = cz - radius; z <= cz + radius; z++){
    for(int y = (cy - radius); y < (cy + radius); y++){
    double dist = (cx - x) * (cx - x) + (cz - z) * (cz - z) + ((cy - y) * (cy - y));

    if(dist < radius * radius){
    Location l = new Location(loc.getWorld(), x, y + 2, z);
    if (l.getBlock().getType() == Material.CHEST) {
    return l;
    }
    }
    }
    }
    }
    return null;
    }
     
    • Like Like x 1
  5. And to store items use:
    Chest chest = (Chest)chestlocation.getBlock().getState();
    chest.getInventory().addItem(new ItemStack(Material.DIAMOND);
     
    • Like Like x 1
  6. Thanks for this :D
     
  7. NathanWolf

    Supporter

  8. Well, technically it's still 3D (a chunk has three dimensions after all), but you're right, looking for TileEntities should vastly reduce the amount of things he'll have to go through. Though in this instance (for a 5 block radius) I'm not sure whether it'll really save all that much, given that you'll inevitably have some overhead to find the relevant chunks.
     
  9. NathanWolf

    Supporter

    You are searching a 2D grid of chunks, and then a list within each chunk .. So I guess, yes, technically 3D, in a way.

    Let's do some math, though.

    Let's pessimistically assume you have 100 tile entities per chunk on average. That'd be a lot, but it will make the math easy and prove my point.

    Scanning just a 16 block radius, you will have to look through at least 4 chunks.

    Scanning blocks, this will involve checking 4x16x16x256 blocks. That is 262,144 blocks.

    Scanning for tile entities, you just have to look at 400.

    The problem gets exponentially worse as your radius increases.

    I highly suggest you look at tile entities ;)
     
  10. Actually, since he's interested in a 5 block radius, it'd be at most 10x10x10 = 100 blocks, or less if he's going for a sphere and not a cube. Still, I'm not disputing that your solution scales far better, just pointing out that for lower radii there might be merit to the more intuitive approach.
     
    • Agree Agree x 1
  11. How would I get the player? Like this?
    I've done this but it doesn't seem to store the items in the chest...
    Code (Text):
        public static Location chests(Location loc, int radius){
            int cx = loc.getBlockX();
            int cy = loc.getBlockY();
            int cz = loc.getBlockZ();

            for(int x = cx - radius; x <= cx + radius; x++){
                for (int z = cz - radius; z <= cz + radius; z++){
                    for(int y = (cy - radius); y < (cy + radius); y++){
                        double dist = (cx - x) * (cx - x) + (cz - z) * (cz - z) + ((cy - y) * (cy - y));
                        if(dist < radius * radius){
                            Location l = new Location(loc.getWorld(), x, y + 2, z);
                            if (l.getBlock().getType() == Material.CHEST) {
                                Chest chest = (Chest)l.getBlock().getState();
                                chest.getInventory().addItem(new ItemStack(Material.DIAMOND));
                                return l;
                            }
                        }
                    }
                }
            }
            return null;
        }
    Code (Text):
         chests(p.getLocation(), 5);
     
  12. jflory7

    jflory7 Retired Moderator
    Retired Benefactor

    Thread locked per request
     
Thread Status:
Not open for further replies.