How to check for a block formation?

Discussion in 'Spigot Plugin Development' started by yhl, Apr 29, 2017.

  1. yhl

    yhl

  2. Try this thing:

    Code (Text):

    import org.bukkit.Material;
    import org.bukkit.block.Block;

    public class FormationDetector
    {
        Material[][][] array;

        public FormationDetector(Material[][][] array)
        {
            this.array = array;
        }

        public boolean Check(Block nat)
        {
            if (nat == null) { return false; }

            for (int i = 0; i < array.length; i++)
            {
                for (int j = 0; j < array[i].length; j++)
                {
                    for (int k = 0; k < array[i][j].length; k++)
                    {
                        if ((array[i][j][k] == null || (array[i][j][k] != null && nat.getType().equals(array[i][j][k])))
                                && Check(nat, i, j, k)) { return true; }
                    }
                }
            }

            return false;
        }

        private boolean Check(Block nat, int xOffset, int yOffset, int zOffset)
        {
            for (int i = 0; i < array.length; i++)
            {
                for (int j = 0; j < array[i].length; j++)
                {
                    for (int k = 0; k < array[i][j].length; k++)
                    {
                        if (array[i][j][k] != null && !nat.getRelative(i - xOffset, j - yOffset, k - zOffset)
                                        .getType().equals(array[i][j][k])) { return false; }
                    }
                }
            }

            return true;
        }
    }
    This is class I have written a while ago. You can create map of materials and pass it to its constructor, then when player clicks on block, which you can detect by handling PlayerInteractEvent, obtain clicked Block object and pass into Check(Block) method - if clicked block and blocks around it will match to given Material[][][] array, it will return true:

    Code (Text):
        FormationDetector formationDetector;
       
        @EventHandler
        public void onInteract(PlayerInteractEvent ev)
        {
            if (formationDetector.Check(ev.getClickedBlock()))
            {
                ev.getPlayer().sendMessage("YES");
            }
            else
            {
                ev.getPlayer().sendMessage("NO");
            }
        }
    When material in material array is nullified, then it will be ignored - any block may be put on that place. It should work, I have tested it quickly. It may be optimized, but I leave it to You ;).
     
  3. What @An0nym8us wrote might work, haven't checked, but it looks amazing.
    Personally I would just listen to a BlockPlaceEvent and check the surrounding blocks to see if they match