/**
   * We listen to BlockPlace events for obvious reasons.
   *
   * @param event the event
   */
  @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
  public void onBlockPlace(final BlockPlaceEvent event) {
    /*
     *  ____  _            _      ____  _
     * | __ )| | ___   ___| | __ |  _ \| | __ _  ___ ___
     * |  _ \| |/ _ \ / __| |/ / | |_) | |/ _` |/ __/ _ \
     * | |_) | | (_) | (__|   <  |  __/| | (_| | (_|  __/
     * |____/|_|\___/ \___|_|\_\ |_|   |_|\__,_|\___\___|
     */

    final Block block = event.getBlockPlaced();
    final Block blockAgainst = event.getBlockAgainst();
    // We don't care about null blocks.
    if (block == null || blockAgainst == null) return;

    final Material mat = block.getType();
    final Player player = event.getPlayer();
    boolean cancelled = false;

    // Check if the block may be placed against a certain material.
    // TODO: Maybe make it an extra check after all.
    final int againstId = blockAgainst.getTypeId();
    if (BlockProperties.isLiquid(againstId)) {
      if ((mat != Material.WATER_LILY
              || !BlockProperties.isLiquid(block.getRelative(BlockFace.DOWN).getTypeId()))
          && !player.hasPermission(Permissions.BLOCKPLACE_AGAINST_LIQUIDS)) cancelled = true;
    } else if (againstId == Material.AIR.getId()) {
      if (!player.hasPermission(Permissions.BLOCKPLACE_AGAINST_AIR)) cancelled = true;
    }

    // First, the fast place check.
    if (fastPlace.isEnabled(player)) {
      if (fastPlace.check(player, block)) cancelled = true;
      else // Combined speed:
      if (Improbable.check(player, 1f, System.currentTimeMillis())) cancelled = true;
    }

    // Second, the no swing check (player doesn't swing his arm when placing a lily pad).
    if (!cancelled
        && mat != Material.WATER_LILY
        && noSwing.isEnabled(player)
        && noSwing.check(player)) cancelled = true;

    // Third, the reach check.
    if (!cancelled && reach.isEnabled(player) && reach.check(player, block.getLocation()))
      cancelled = true;

    // Fourth, the direction check.
    if (!cancelled
        && direction.isEnabled(player)
        && direction.check(player, block.getLocation(), blockAgainst.getLocation()))
      cancelled = true;

    // If one of the checks requested to cancel the event, do so.
    if (cancelled) event.setCancelled(cancelled);
  }
Example #2
0
 public void free() {
   for (Reach r : reach) {
     r.free();
   }
 }
Example #3
0
 public boolean reachable(String a, String b) {
   for (Reach r : reach) {
     if (r.reachable(a, b)) return true;
   }
   return false;
 }