Loop Blocks in Radius

Discussion in 'Plugin Help/Development/Requests' started by BrickBoy55, Apr 3, 2015.

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

    BrickBoy55

    How would one loop blocks in a radius with the player as the middle point?
     
    Last edited: Apr 3, 2015
  2. Invisible

    nverdier

    @BrickBoy55 Use three nested loops to get x, y, and z.
     
  3. Offline

    BrickBoy55

    @nverdier
    Now I really have an error.

    This is what I have:
    Show Spoiler

    Code:
        @EventHandler
        public void onBreak(BlockBreakEvent event) {
            Player player = event.getPlayer();
            double radius = 25;
            Location loc= player.getLocation();
           
            List<Block> blocks = new ArrayList<Block>();
           
            for(double x = loc.getX() - radius; x < loc.getX() + radius; x++ ) {
                 for(double y = loc.getY() - radius; y < loc.getY() + radius; y++ ) {
                     for (double z = loc.getZ() - radius; z < loc.getZ() + radius; z++ ) {
                           Location location = new Location(player.getWorld(), x, y, z);
                           blocks.add(location.getBlock());
                           
                           for (Block block : blocks) {
                              if (block.getType().equals(Material.SIGN)) {
                                  Sign sign = (Sign) block;
                                 
                                  if (sign.getLine(0).equals("§8[§9Protected§8]")) {
                                      if (sign.getLine(1).equals("§4" + player.getName())) {
                                          return;
                                      } else {
                                          event.setCancelled(true);
                                      }
                                  }
                              }
                           }
                     }
             }
            }
        }
    


    But whenever I break a block, the server lags for 60 seconds, until it says it has gone too long without a response and will shut down.

    I tried changing it to an int, and it still didn't work.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 10, 2016
  4. Offline

    MexMaster

  5. Offline

    BrickBoy55

    @MexMaster

    EDIT: It finally created a crash-report:

    Error Line:
    Code:
    if (block.getType().equals(Material.SIGN)) {
    
    Error:
    Show Spoiler

    java.lang.Error
    at org.bukkit.craftbukkit.v1_8_R1.block.CraftBlock.getType(CraftBlock.java:148)
    at org.brick.protect.Protect.onBreak(Protect.java:90)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:295)
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:501)
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:486)
    at net.minecraft.server.v1_8_R1.PlayerInteractManager.breakBlock(PlayerInteractManager.java:285)
    at net.minecraft.server.v1_8_R1.PlayerInteractManager.a(PlayerInteractManager.java:121)
    at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java:573)
    at net.minecraft.server.v1_8_R1.PacketPlayInBlockDig.a(SourceFile:40)
    at net.minecraft.server.v1_8_R1.PacketPlayInBlockDig.a(SourceFile:10)
    at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:645)
    at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:284)
    at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:598)
    at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:506)
    at java.lang.Thread.run(Thread.java:745)
     
  6. Offline

    MexMaster

    @BrickBoy55
    Instead of
    "block.getType().equals(Material.SIGN)"
    try
    "block.getType() == Material.SIGN"

    Also check for WALL_SIGN and SIGN_POST maybe
     
  7. Offline

    BrickBoy55

  8. Offline

    MexMaster

  9. Offline

    BrickBoy55

  10. Offline

    MexMaster

    @BrickBoy55
    That should not fix your issue but prevent another one. Replace
    "Sign sign = (Sign) block;"
    with
    "Sign sign = (Sign) block.getState();"

    //edit:
    There seems to be something wrong with getType();
    Try getTypeId(); and print that value out and please post it here
     
    Last edited: Apr 3, 2015
  11. Offline

    BrickBoy55

    @MexMaster

    EDIT: Did it again, different results:

    Error line is now:
    Code:
    if (block.getTypeId() == 323) {
    
    again.

    Whole class:
    Show Spoiler

    Code:
    package org.brick.protect;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.bukkit.Location;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.block.Block;
    import org.bukkit.block.Sign;
    //import org.bukkit.command.Command;
    //import org.bukkit.command.CommandSender;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.event.block.SignChangeEvent;
    import org.bukkit.entity.Player;
    
    public class Protect extends JavaPlugin implements Listener {
        public String prefix = "§8[§4Protect§8] §9";
      
        @Override
        public void onEnable() {
            //saveDefaultConfig();
            getServer().getPluginManager().registerEvents(this, this);
            getLogger().info("Successfully enabled!");
        }
      
        @Override
        public void onDisable() {
            getLogger().info("Successfully disabled!");
        }
      
        /*
        public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
            if (command.getName().equalsIgnoreCase("protect")) {
                if (!(sender instanceof Player)) {
                    reloadConfig();
                    sender.sendMessage("[Protect] Configuration reloaded!");
                } else {
                    Player player = (Player) sender;
                    reloadConfig();
                    player.sendMessage(prefix + "Configuration reloaded!");
                }
            }
          
            return false;
        }
        */
      
        @EventHandler
        public void onSignChange(SignChangeEvent event) {
            Player player = event.getPlayer();
          
            if (event.getLine(0).equals("[PROTECT]")) {
                if (event.getLine(1).equals(player.getName())) {
                    event.setLine(0, "§8[§9Protected§8]");
                    event.setLine(1, "§4" + player.getName());
                  
                    if (event.getLine(2) != null) {
                        event.setLine(2, "§4" + event.getLine(2));
                    }
                  
                    if (event.getLine(3) != null) {
                        event.setLine(3, "§4" + event.getLine(3));
                    }
                  
                    player.sendMessage(prefix + "Area protected!");
                } else {
                    player.sendMessage(prefix + "Line 2 of the sign must be your username!");
                }
            }
        }
      
        @SuppressWarnings("deprecation")
        @EventHandler
        public void onBreak(BlockBreakEvent event) {
            Player player = event.getPlayer();
            int radius = 25;
            Location loc= player.getLocation();
          
            List<Block> blocks = new ArrayList<Block>();
          
            for(int x = (int) (loc.getX() - radius); x < loc.getX() + radius; x++ ) {
                 for(int y = (int) (loc.getY() - radius); y < loc.getY() + radius; y++ ) {
                     for (int z = (int) (loc.getZ() - radius); z < loc.getZ() + radius; z++ ) {
                           Location location = new Location(player.getWorld(), x, y, z);
                           blocks.add(location.getBlock());
                          
                           for (Block block : blocks) {
                              if (block.getTypeId() == 323) {
                                  Sign sign = (Sign) block.getState();
                                
                                  if (sign.getLine(0).equals("§8[§9Protected§8]")) {
                                      if (sign.getLine(1).equals("§4" + player.getName())) {
                                          return;
                                      } else {
                                          event.setCancelled(true);
                                      }
                                  }
                              }
                           }
                     }
             }
            }
        }
    }
    
    


    Error:
    Show Spoiler

    Code:
    
    java.lang.Error
        at org.brick.protect.Protect.onBreak(Protect.java:90)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:295)
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
        at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:501)
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:486)
        at net.minecraft.server.v1_8_R1.PlayerInteractManager.breakBlock(PlayerInteractManager.java:285)
        at net.minecraft.server.v1_8_R1.PlayerInteractManager.a(PlayerInteractManager.java:121)
        at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java:573)
        at net.minecraft.server.v1_8_R1.PacketPlayInBlockDig.a(SourceFile:40)
        at net.minecraft.server.v1_8_R1.PacketPlayInBlockDig.a(SourceFile:10)
        at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:645)
        at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:284)
        at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:598)
        at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:506)
        at java.lang.Thread.run(Thread.java:745)
    
     
  12. Offline

    MexMaster

    @BrickBoy55
    Hmm...
    Maybe removing the whole for block helps in any way. Because the loop over all blocks isn't even needed that often.
    I mean you start at block number 1 in the radius. You add this block to the list and then check every block in the list. You continue to block number 2. You add it to the list and them you check all blocks in that list, number 1 and number 2. But you already tested for number 1.
    So just remove the for block and check the block that you add to the list. And remove the list also
     
  13. Offline

    BrickBoy55

  14. Offline

    MexMaster

    @BrickBoy55
    Your list part is completely unnecessary.
    Just do:

    for x
    for y
    for z
    //Not add the block to a list and not check the whole list
    Block b = new Location(player.getWorld(), x, y, z).getBlock();
    checkBlock for sign here
     
  15. Invisible

    nverdier

  16. Offline

    BrickBoy55

    @MexMaster @nverdier
    So I do my fore statements, then:
    Code:
    if (player.getWorld().getBlockAt(x, y, z).getType().equals(Material.SIGN)) {}
    
    ?
     
  17. Invisible

    nverdier

    @BrickBoy55 You have to check for 'WALL_SIGN' or 'SIGN_POST' instead of Sign.
     
  18. Offline

    MexMaster

  19. Offline

    BrickBoy55

    @nverdier

    Code:
    if (player.getWorld().getBlockAt(x, y, z).getType().equals(Material.WALL_SIGN) || player.getWorld().getBlockAt(x, y, z).getType().equals(Material.WALL_SIGN) ) {
                             Sign sign = (Sign) player.getWorld().getBlockAt(x, y, z);
    }
    
    Would this work?
     
  20. Invisible

    nverdier

    @MexMaster Because Material.SIGN is when it's in your inventory. It of one of the ones I previously posted if it's placed.


    @BrickBoy55 Test it! But to make it more efficient, create a Block variable and use that in place of all of the player.getWorld.getBlockAt...
     
  21. Offline

    BrickBoy55

    @nverdier @MexMaster

    It worked!

    Solution:
    Code:
        @EventHandler
        public void onBreak(BlockBreakEvent event) {
            Player player = event.getPlayer();
            int radius = 25;
            Location loc= player.getLocation();
           
            for(int x = (int) (loc.getX() - radius); x < loc.getX() + radius; x++ ) {
                 for(int y = (int) (loc.getY() - radius); y < loc.getY() + radius; y++ ) {
                     for (int z = (int) (loc.getZ() - radius); z < loc.getZ() + radius; z++ ) {
                         
                         if (player.getWorld().getBlockAt(x, y, z).getType().equals(Material.WALL_SIGN) || player.getWorld().getBlockAt(x, y, z).getType().equals(Material.WALL_SIGN) ) {
                             Sign sign = (Sign) player.getWorld().getBlockAt(x, y, z);
                             
                              if (sign.getLine(0).equals("§8[§9Protected§8]")) {
                                  if (sign.getLine(1).equals("§4" + player.getName())) {
                                      return;
                                  } else {
                                      event.setCancelled(true);
                                  }
                              }
                         }
                     }
                 }
            }
        }
    
     
  22. Invisible

    nverdier

  23. Offline

    BrickBoy55

    @nverdier

    Unfortunately I have a different problem now, but I'll try to fix it before making a post (if i need it)
     
  24. Invisible

    nverdier

  25. Offline

    MexMaster

    @nverdier
    But why is he getting an 'Error' when just comparing to objects?
     
  26. Invisible

    nverdier

    @MexMaster It's probably not a compilation error...
     
  27. Offline

    BrickBoy55

    @nverdier

    Yeah well, the problem is that if your name isn't the name on line 2 of the sign, you can still break blocks.

    Code:
        @EventHandler
        public void onBreak(BlockBreakEvent event) {
            Player player = event.getPlayer();
            int radius = 25;
            Location loc= player.getLocation();
           
            for(int x = (int) (loc.getX() - radius); x < loc.getX() + radius; x++ ) {
                 for(int y = (int) (loc.getY() - radius); y < loc.getY() + radius; y++ ) {
                     for (int z = (int) (loc.getZ() - radius); z < loc.getZ() + radius; z++ ) {
                         
                         if (player.getWorld().getBlockAt(x, y, z).getType().equals(Material.WALL_SIGN) || player.getWorld().getBlockAt(x, y, z).getType().equals(Material.WALL_SIGN) ) {
                             Sign sign = (Sign) player.getWorld().getBlockAt(x, y, z);
                             
                              if (sign.getLine(0).equals("§8[§9Protected§8]")) {
                                  if (!player.getName().equals(sign.getLine(1))) {
                                      event.setCancelled(true);
                                  }
                              }
                         }
                     }
                 }
            }
        }
    
     
  28. Invisible

    nverdier

  29. Offline

    BrickBoy55

    @nverdier

    I want it so the player who's name is on line 2 of the sign, to be able to build in that area, but other people who's name isn't on line two, to not be able to build. Does that make sense, sorry if I'm confusing.
     
  30. Offline

    MexMaster

    @BrickBoy55
    You're testing for WALL_SIGN both times. But you have to test for WALL_SIGN and SIGN_POST.
    Also do you get an error? You have to cast the block.getState(); instead of the block to Sign
     
Thread Status:
Not open for further replies.

Share This Page