Example #1
0
 static {
   for (BlockFace face1 : new BlockFace[] {BlockFace.THIS, BlockFace.TOP, BlockFace.BOTTOM}) {
     for (BlockFace face2 : new BlockFace[] {BlockFace.THIS, BlockFace.WEST, BlockFace.EAST}) {
       for (BlockFace face3 : new BlockFace[] {BlockFace.THIS, BlockFace.NORTH, BlockFace.SOUTH}) {
         BlockFaces faces = new BlockFaces(face1, face2, face3);
         Vector3 offset = faces.getOffset();
         byte hash = getOffsetHash(offset);
         offsetHash.put(hash, faces);
       }
     }
   }
 }
Example #2
0
/** Contains several BlockFace array constants and functions to operate on them */
public class BlockFaces implements Iterable<BlockFace>, ByteBitMask {

  private static TByteObjectHashMap<BlockFaces> offsetHash = new TByteObjectHashMap<BlockFaces>();

  static {
    for (BlockFace face1 : new BlockFace[] {BlockFace.THIS, BlockFace.TOP, BlockFace.BOTTOM}) {
      for (BlockFace face2 : new BlockFace[] {BlockFace.THIS, BlockFace.WEST, BlockFace.EAST}) {
        for (BlockFace face3 : new BlockFace[] {BlockFace.THIS, BlockFace.NORTH, BlockFace.SOUTH}) {
          BlockFaces faces = new BlockFaces(face1, face2, face3);
          Vector3 offset = faces.getOffset();
          byte hash = getOffsetHash(offset);
          offsetHash.put(hash, faces);
        }
      }
    }
  }

  /** The [top-bottom] faces */
  public static final BlockFaces TB = new BlockFaces(BlockFace.TOP, BlockFace.BOTTOM);

  /** The [bottom-top] faces */
  public static final BlockFaces BT = new BlockFaces(BlockFace.BOTTOM, BlockFace.TOP);

  /** The [north-east-south-west] faces */
  public static final BlockFaces NESW =
      new BlockFaces(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST);

  /** The [north-south-east-west] faces */
  public static final BlockFaces NSEW =
      new BlockFaces(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST);

  /** The [east-west-south-north] faces */
  public static final BlockFaces EWSN =
      new BlockFaces(BlockFace.EAST, BlockFace.WEST, BlockFace.SOUTH, BlockFace.NORTH);

  /** The [north-south-west-east] faces */
  public static final BlockFaces NSWE =
      new BlockFaces(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, BlockFace.EAST);

  /** The [south-west-north-east] faces */
  public static final BlockFaces SWNE =
      new BlockFaces(BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH, BlockFace.EAST);

  /** The [west-north-east-south] faces */
  public static final BlockFaces WNES =
      new BlockFaces(BlockFace.WEST, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH);

  /** The [west-south-east-north] faces */
  public static final BlockFaces WSEN =
      new BlockFaces(BlockFace.WEST, BlockFace.SOUTH, BlockFace.EAST, BlockFace.NORTH);

  /** The [south-north-east-west] faces */
  public static final BlockFaces SNEW =
      new BlockFaces(BlockFace.SOUTH, BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST);

  /** The [west-east-south-north] faces */
  public static final BlockFaces WESN =
      new BlockFaces(BlockFace.WEST, BlockFace.EAST, BlockFace.SOUTH, BlockFace.NORTH);

  /** The [south-north-west-east] faces */
  public static final BlockFaces SNWE =
      new BlockFaces(BlockFace.SOUTH, BlockFace.NORTH, BlockFace.WEST, BlockFace.EAST);

  /** The [east-south-west-north] faces */
  public static final BlockFaces ESWN =
      new BlockFaces(BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH);

  /** The [east-west-north-south] faces */
  public static final BlockFaces EWNS =
      new BlockFaces(BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH);

  /** The [north-east-south-west-bottom] faces */
  public static final BlockFaces NESWB = NESW.append(BlockFace.BOTTOM);

  /** The [east-west-south-north-bottom] faces */
  public static final BlockFaces EWSNB = EWSN.append(BlockFace.BOTTOM);

  /** The [north-east-south-west-top] faces */
  public static final BlockFaces NESWT = NESW.append(BlockFace.TOP);

  /** The [north-east-south-west-bottom-top] faces */
  public static final BlockFaces NESWBT = NESW.append(BT);

  /** The [bottom-top-east-west-north-south] faces */
  public static final BlockFaces BTEWNS = BT.append(EWNS);

  /** The [bottom-top-north-south-west-east] faces */
  public static final BlockFaces BTNSWE = BT.append(NSWE);

  /** The [north-south-east-west-bottom] faces */
  public static final BlockFaces NSEWB = NSEW.append(BlockFace.BOTTOM);

  /** The [north-south-west-east-bottom] faces */
  public static final BlockFaces NSWEB = NSWE.append(BlockFace.BOTTOM);

  /** The [north-east-south-west-bottom-this] faces */
  public static final BlockFaces NESWBTHIS = NESWB.append(BlockFace.THIS);

  /** The [top-bottom-north-south-east-west-this] faces */
  public static final BlockFaces ALL = new BlockFaces(BlockFace.values());

  /** A constant containing no faces at all */
  public static final BlockFaces NONE = new BlockFaces();

  private final byte mask;
  private final BlockFace[] faces;
  private final Vector3 offset;

  public BlockFaces(BlockFace... blockfaces) {
    this.faces = blockfaces;
    byte mask = 0;
    Vector3 offsetc = new Vector3();
    for (BlockFace face : this.faces) {
      offsetc = offsetc.add(face.getOffset());
      mask |= face.getMask();
    }
    offset = offsetc;
    this.mask = mask;
  }

  @Override
  public byte getMask() {
    return this.mask;
  }

  public Vector3 getOffset() {
    return offset;
  }

  @Override
  public Iterator<BlockFace> iterator() {
    return Arrays.asList(this.faces).iterator();
  }

  /**
   * Gets the total amount of BlockFace objects contained in this constant
   *
   * @return the amount of BlockFace objects
   */
  public int size() {
    return this.faces.length;
  }

  /**
   * Appends another array of block faces to this BlockFaces object
   *
   * @param blockFaces to append
   * @return a new BlockFaces object with the faces appended
   */
  public BlockFaces append(BlockFaces blockFaces) {
    return this.append(blockFaces.faces);
  }

  /**
   * Appends another array of block faces to this BlockFaces object
   *
   * @param blockFaces to append
   * @return a new BlockFaces object with the faces appended
   */
  public BlockFaces append(BlockFace... blockFaces) {
    BlockFace[] faces = new BlockFace[this.faces.length + blockFaces.length];
    for (int i = 0; i < this.faces.length; i++) {
      faces[i] = this.faces[i];
    }
    for (int i = 0; i < blockFaces.length; i++) {
      faces[i + this.faces.length] = blockFaces[i];
    }
    return new BlockFaces(faces);
  }

  /**
   * Checks if this block face constant contains the face given
   *
   * @param face to look for
   * @return True if found, False if not
   */
  public boolean contains(BlockFace face) {
    for (BlockFace bface : this.faces) {
      if (bface == face) {
        return true;
      }
    }
    return false;
  }

  /**
   * Gets the index of a face in this constant
   *
   * @param face to get the index of
   * @param def value to return if not found
   * @return the index in the constant, or the def value if not found
   */
  public int indexOf(BlockFace face, int def) {
    for (int i = 0; i < this.faces.length; i++) {
      if (this.faces[i] == face) {
        return i;
      }
    }
    return def;
  }

  /**
   * Gets the previous BlockFace in this circular BlockFaces constant<br>
   * This function calls next using a negative offset
   *
   * @see BlockFaces.next(BlockFace from, int offset);
   * @param from the BlockFace to count
   * @param offset index in this range
   * @return the face at the offset
   */
  public BlockFace previous(BlockFace from, int offset) {
    return this.next(from, -offset);
  }

  /**
   * Gets the next BlockFace in this circular BlockFaces constant<br>
   * <br>
   * <b>For example:</b><br>
   * BlockFaces.NESW.next(BlockFace.EAST, 2) == BlockFace.WEST<br>
   * BlockFaces.NESW.next(BlockFace.WEST, 1) == BlockFace.NORTH<br>
   * BlockFaces.NESW.next(BlockFace.SOUTH, -3) == BlockFace.WEST<br>
   *
   * @param from the BlockFace to count
   * @param offset index in this range
   * @return the face at the offset
   */
  public BlockFace next(BlockFace from, int offset) {
    int index = this.indexOf(from, -1);
    if (index == -1) {
      throw new IllegalArgumentException(
          "This BlockFaces constant does not contain the face specified");
    }
    index = (index + offset) % this.faces.length;
    if (index < 0) {
      index += this.faces.length;
    }
    return this.faces[index];
  }

  /**
   * Gets a random BlockFace from this BlockFaces constant
   *
   * @param random to use
   * @return a random BlockFace
   */
  public BlockFace random(Random random) {
    return this.faces[random.nextInt(this.faces.length)];
  }

  /**
   * Gets the face from this constant at the index given<br>
   * If the index is out of range, the first or last element is returned
   *
   * @param index to get at
   * @return the BlockFace
   */
  public BlockFace get(int index) {
    if (index < 0) {
      return this.faces[0];
    } else if (index >= this.faces.length) {
      return this.faces[this.faces.length - 1];
    } else {
      return this.faces[index];
    }
  }

  /**
   * Gets the face from this constant at the index given<br>
   * If the index is out of range, the default is returned
   *
   * @param index to get at
   * @param def if the index is out of range
   * @return the BlockFace
   */
  public BlockFace get(int index, BlockFace def) {
    if (index < 0 || index >= this.faces.length) {
      return def;
    }

    return this.faces[index];
  }

  private static byte getOffsetHash(Vector3 offset) {
    offset = offset.normalize();
    offset = offset.round();
    int x = offset.getFloorX();
    int y = offset.getFloorY();
    int z = offset.getFloorZ();
    x += 1;
    y += 1;
    z += 1;
    return (byte) (x | y << 2 | z << 4);
  }

  public static BlockFaces fromOffset(Vector3 offset) {
    return offsetHash.get(getOffsetHash(offset));
  }
}