/**
   * @param player
   * @param field
   */
  public void addFieldMark(Player player, Field field) {
    Visualization vis = visualizations.get(player.getName());

    if (vis == null) {
      vis = new Visualization();
    }

    vis.addField(field);

    World world = plugin.getServer().getWorld(field.getWorld());

    if (world != null) {
      for (int y = 0; y < 256; y++) {
        int typeId = world.getBlockTypeIdAt(field.getX(), y, field.getZ());

        if (plugin.getSettingsManager().isThroughType(typeId)) {
          vis.addBlock(
              new Location(world, field.getX(), y, field.getZ()),
              plugin.getSettingsManager().getVisualizeMarkBlock(),
              (byte) 0);
        }
      }
    }

    visualizations.put(player.getName(), vis);
  }
  private boolean isEmptySpace(World world, int x, int y, int z) {
    int type1 = world.getBlockTypeIdAt(x, y, z);
    int type2 = world.getBlockTypeIdAt(x, y, z);

    if (plugin.getSettingsManager().isThroughType(type1)
        && plugin.getSettingsManager().isThroughType(type2)) {
      return true;
    }

    return false;
  }
  /**
   * Whether SimpleClans was loaded
   *
   * @return
   */
  public boolean hasSimpleClans() {
    if (plugin.getSettingsManager().isDisableSimpleClanHook()) {
      return false;
    }

    return simpleClans != null;
  }
  /** @param event */
  @EventHandler(priority = EventPriority.HIGH)
  public void onVehicleMove(VehicleMoveEvent event) {
    Vehicle v = event.getVehicle();
    Entity entity = v.getPassenger();

    if (plugin.getSettingsManager().isBlacklistedWorld(v.getLocation().getWorld())) {
      return;
    }

    if (!(entity instanceof Player)) {
      return;
    }

    plugin
        .getPlayerListener()
        .onPlayerMove(new PlayerMoveEvent((Player) entity, event.getFrom(), event.getTo()));
  }
  /**
   * Whether the player has reached the placing limit for a field
   *
   * @param player
   * @param fs the field settings of the field you need to get the limit of
   * @return
   */
  public boolean reachedLimit(Player player, FieldSettings fs) {
    List<Integer> limits = fs.getLimits();

    if (limits.isEmpty()) {
      return false;
    }

    if (plugin.getPermissionsManager().has(player, "preciousstones.bypass.limits")) {
      return false;
    }

    int limit = getLimit(player, fs);
    int count =
        plugin.getForceFieldManager().getFieldCount(player.getName(), fs.getTypeEntry())
            + plugin
                .getForceFieldManager()
                .getRentedFieldCount(player.getName(), fs.getTypeEntry());

    if (limit == -1) {
      return false;
    }

    if (limit == 0) {
      ChatHelper.send(player, "limitsCannotPlace", fs.getTitle());
      return true;
    }

    if (count >= limit) {
      ChatHelper.send(player, "limitsReached", fs.getTitle(), limit);
      return true;
    }

    int totalCount = plugin.getForceFieldManager().getTotalFieldCount(player.getName());

    if (totalCount >= plugin.getSettingsManager().getGlobalFieldLimit()) {
      ChatHelper.send(player, "limitsReachedGlobal", limit);
      return true;
    }

    return false;
  }
  @Override
  public void onBlockBreak(BlockBreakEvent event) {
    if (event.isCancelled()) return;

    final Block block = event.getBlock();

    if (!stones.getSettingsManager().isFieldType(event.getBlock()) && !BlockUtil.isSign(block))
      return;

    // SignCheck
    if (BlockUtil.isSign(block)) {
      final Player player = event.getPlayer();
      final Block fieldBlock = BlockUtil.getFieldStone(block, false);
      // Check if fieldBlock has a known field
      if (fieldBlock == null) {
        return;
      }
      // Get ExpensiveField and dormant it.
      final ExpensiveField field = fieldManager.getExpensiveField(fieldBlock);
      fieldManager.setDormantField(field);
      player.sendMessage(ChatColor.YELLOW + "ExpensiveStones: Field is succesfully dormanted.");
      return;
    }
    // Check if block is known to ExpensiveField
    if (fieldManager.isKnown(block)) {
      final ExpensiveField field = fieldManager.getExpensiveField(block);

      field.setFieldON();
      if (!fieldManager.isInDormant(field.getField().getLocation())) field.setError();
      fieldManager.removeField(field);

      event
          .getPlayer()
          .sendMessage(ChatColor.YELLOW + "ExpensiveStones: Field is ready to be deleted.");
    }
  }
 private boolean blockIsSafe(World world, int x, int y, int z) {
   int head = world.getBlockTypeIdAt(x, y + 1, z);
   int feet = world.getBlockTypeIdAt(x, y, z);
   return (plugin.getSettingsManager().isThroughType(head))
       && (plugin.getSettingsManager().isThroughType((feet)));
 }
  /**
   * Adds a fields perimeter to a player's visualization buffer
   *
   * @param player
   * @param field
   */
  public void addVisualizationField(Player player, Field field) {
    Visualization vis = visualizations.get(player.getName());

    if (vis == null) {
      vis = new Visualization();
    }

    if (plugin.getCuboidManager().hasOpenCuboid(player)) {
      return;
    }

    PlayerEntry data = plugin.getPlayerManager().getPlayerEntry(player.getName());

    if (data.getDensity() == 0) {
      return;
    }

    vis.addField(field);

    int visualizationType =
        field.hasFlag(FieldFlag.CUBOID)
            ? plugin.getSettingsManager().getCuboidVisualizationType()
            : plugin.getSettingsManager().getVisualizeBlock();
    int frameType = plugin.getSettingsManager().getVisualizeFrameBlock();

    int minx = field.getX() - field.getRadius() - 1;
    int maxx = field.getX() + field.getRadius() + 1;
    int minz = field.getZ() - field.getRadius() - 1;
    int maxz = field.getZ() + field.getRadius() + 1;
    int miny = field.getY() - (Math.max(field.getHeight() - 1, 0) / 2) - 1;
    int maxy = field.getY() + (Math.max(field.getHeight() - 1, 0) / 2) + 1;

    if (field.hasFlag(FieldFlag.CUBOID)) {
      minx = field.getMinx() - 1;
      maxx = field.getMaxx() + 1;
      minz = field.getMinz() - 1;
      maxz = field.getMaxz() + 1;
      miny = field.getMiny() - 1;
      maxy = field.getMaxy() + 1;
    }

    Location loc = null;

    for (int x = minx; x <= maxx; x++) {
      int frame = (x == minx || x == maxx) ? 89 : frameType;

      loc = new Location(player.getWorld(), x, miny, maxz);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, frame, (byte) 0);
      }

      loc = new Location(player.getWorld(), x, maxy, minz);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, frame, (byte) 0);
      }

      loc = new Location(player.getWorld(), x, miny, minz);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, frame, (byte) 0);
      }

      loc = new Location(player.getWorld(), x, maxy, maxz);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, frame, (byte) 0);
      }
    }

    for (int y = miny; y <= maxy; y++) {
      loc = new Location(player.getWorld(), minx, y, maxz);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, 89, (byte) 0);
      }

      loc = new Location(player.getWorld(), maxx, y, minz);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, 89, (byte) 0);
      }

      loc = new Location(player.getWorld(), minx, y, minz);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, 89, (byte) 0);
      }

      loc = new Location(player.getWorld(), maxx, y, maxz);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, 89, (byte) 0);
      }
    }

    for (int z = minz; z <= maxz; z++) {
      int frame = (z == minz || z == maxz) ? 89 : frameType;

      loc = new Location(player.getWorld(), minx, maxy, z);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, frame, (byte) 0);
      }

      loc = new Location(player.getWorld(), maxx, miny, z);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, frame, (byte) 0);
      }

      loc = new Location(player.getWorld(), minx, miny, z);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, frame, (byte) 0);
      }

      loc = new Location(player.getWorld(), maxx, maxy, z);
      if (Helper.isAirOrWater(loc)) {
        vis.addBlock(loc, frame, (byte) 0);
      }
    }

    visualizations.put(player.getName(), vis);
  }
 /**
  * Displays contents of a player's visualization buffer to the player
  *
  * @param player
  * @param minusOverlap
  */
 public void displayVisualization(final Player player, boolean minusOverlap) {
   displayVisualization(player, minusOverlap, plugin.getSettingsManager().getVisualizeSeconds());
 }
  /**
   * Adds a fields outline to a player's visualization buffer
   *
   * @param player
   * @param ce
   */
  public void displayFieldOutline(Player player, CuboidEntry ce) {
    Visualization vis = visualizations.get(player.getName());

    if (vis == null) {
      vis = new Visualization();
    }

    // save current outline and clear out the visualization

    List<BlockEntry> oldBlocks = new ArrayList<BlockEntry>(vis.getOutlineBlocks());
    List<BlockEntry> newBlocks = new ArrayList<BlockEntry>();

    int frameType = plugin.getSettingsManager().getVisualizeFrameBlock();

    int offset = ce.selectedCount() > 1 ? 1 : 0;

    int minx = ce.getMinx() - offset;
    int miny = ce.getMiny() - offset;
    int minz = ce.getMinz() - offset;
    int maxx = ce.getMaxx() + offset;
    int maxy = ce.getMaxy() + offset;
    int maxz = ce.getMaxz() + offset;

    // add  the blocks for the new outline

    if (plugin.getSettingsManager().isVisualizationNewStyle()) {
      PlayerEntry data = plugin.getPlayerManager().getPlayerEntry(player.getName());
      int spacing =
          ((Math.max(Math.max((maxx - minx), (maxy - miny)), (maxz - minz)) + 2)
                  / data.getDensity())
              + 1;

      for (int x = minx; x <= maxx; x++) {
        int frame = (x == minx || x == maxx) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), x, miny, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), x, maxy, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), x, miny, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
        loc = new Location(player.getWorld(), x, maxy, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
      }

      for (int y = miny; y <= maxy; y++) {
        int frame = (y == miny || y == maxy) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, y, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, y, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), minx, y, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, y, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
      }

      for (int z = minz; z <= maxz; z++) {
        int frame = (z == minz || z == maxz) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, maxy, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, miny, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), minx, miny, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, maxy, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
      }
    } else {
      for (int x = minx; x <= maxx; x++) {
        int frame = (x == minx || x == maxx) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), x, miny, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), x, maxy, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), x, miny, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), x, maxy, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
      }

      for (int y = miny; y <= maxy; y++) {
        int frame = (y == miny || y == maxy) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, y, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, y, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), minx, y, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, y, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
      }

      for (int z = minz; z <= maxz; z++) {
        int frame = (z == minz || z == maxz) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, maxy, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, miny, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), minx, miny, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, maxy, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
      }
    }

    // revert the blocks that are no longer in the new set and should be reverted

    List<BlockEntry> revertible = new ArrayList<BlockEntry>(oldBlocks);
    revertible.removeAll(newBlocks);

    Visualize revert =
        new Visualize(
            revertible, player, true, false, plugin.getSettingsManager().getVisualizeSeconds());

    // visualize all the new blocks that are left to visualize

    List<BlockEntry> missing = new ArrayList<BlockEntry>(newBlocks);
    missing.removeAll(oldBlocks);

    Visualize visualize =
        new Visualize(
            missing, player, false, true, plugin.getSettingsManager().getVisualizeSeconds());

    vis.setOutlineBlocks(newBlocks);
    visualizations.put(player.getName(), vis);
  }
  /**
   * Visualizes a single field's outline
   *
   * @param player
   * @param field
   */
  public void visualizeSingleOutline(Player player, Field field, boolean revert) {
    Visualization vis = visualizations.get(player.getName());

    if (vis == null) {
      vis = new Visualization();
    }

    // save current outline and clear out the visualization

    List<BlockEntry> newBlocks = new ArrayList<BlockEntry>();

    int frameType = plugin.getSettingsManager().getVisualizeFrameBlock();

    int minx = field.getX() - field.getRadius() - 1;
    int maxx = field.getX() + field.getRadius() + 1;
    int minz = field.getZ() - field.getRadius() - 1;
    int maxz = field.getZ() + field.getRadius() + 1;
    int miny = field.getY() - (Math.max(field.getHeight() - 1, 0) / 2) - 1;
    int maxy = field.getY() + (Math.max(field.getHeight() - 1, 0) / 2) + 1;

    if (field.hasFlag(FieldFlag.CUBOID)) {
      minx = field.getMinx() - 1;
      maxx = field.getMaxx() + 1;
      minz = field.getMinz() - 1;
      maxz = field.getMaxz() + 1;
      miny = field.getMiny() - 1;
      maxy = field.getMaxy() + 1;
    }

    // add  the blocks for the new outline

    if (plugin.getSettingsManager().isVisualizationNewStyle()) {
      PlayerEntry data = plugin.getPlayerManager().getPlayerEntry(player.getName());
      int spacing =
          ((Math.max(Math.max((maxx - minx), (maxy - miny)), (maxz - minz)) + 2)
                  / data.getDensity())
              + 1;

      for (int x = minx; x <= maxx; x++) {
        int frame = (x == minx || x == maxx) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), x, miny, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), x, maxy, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), x, miny, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), x, maxy, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
      }

      for (int y = miny; y <= maxy; y++) {
        int frame = (y == miny || y == maxy) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, y, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, y, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), minx, y, minz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, y, maxz);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
      }

      for (int z = minz; z <= maxz; z++) {
        int frame = (z == minz || z == maxz) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, maxy, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, miny, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), minx, miny, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }

        loc = new Location(player.getWorld(), maxx, maxy, z);
        if (Helper.isAirOrWater(loc)) {
          newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
        }
      }
    } else {
      for (int x = minx; x <= maxx; x++) {
        int frame = (x == minx || x == maxx) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), x, miny, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), x, maxy, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), x, miny, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), x, maxy, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
      }

      for (int y = miny; y <= maxy; y++) {
        int frame = (y == miny || y == maxy) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, y, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, y, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), minx, y, minz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, y, maxz);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
      }

      for (int z = minz; z <= maxz; z++) {
        int frame = (z == minz || z == maxz) ? 89 : frameType;

        Location loc = new Location(player.getWorld(), minx, maxy, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, miny, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), minx, miny, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));

        loc = new Location(player.getWorld(), maxx, maxy, z);
        newBlocks.add(new BlockEntry(loc, frame, (byte) 0));
      }
    }

    // visualize all the new blocks that are left to visualize

    Visualize visualize =
        new Visualize(
            newBlocks, player, false, !revert, plugin.getSettingsManager().getVisualizeSeconds());
    visualizations.put(player.getName(), vis);
  }