package com.bergerkiller.bukkit.common.bases; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import com.bergerkiller.bukkit.common.utils.MathUtil; /** * Represents a class containing three immutable integer coordinates: x, y and z */ public class IntVector3 implements Comparable<IntVector3> { public static final IntVector3 ZERO = new IntVector3(0, 0, 0); public final int x, y, z; public IntVector3(Block block) { this(block.getX(), block.getY(), block.getZ()); } public IntVector3(final double x, final double y, final double z) { this(MathUtil.floor(x), MathUtil.floor(y), MathUtil.floor(z)); } public IntVector3(final int x, final int y, final int z) { this.x = x; this.y = y; this.z = z; } @Override public String toString() { return "{" + x + ", " + y + ", " + z + "}"; } @Override public boolean equals(Object object) { if (object == this) { return true; } else if (object instanceof IntVector3) { IntVector3 other = (IntVector3) object; return this.x == other.x && this.y == other.y && this.z == other.z; } else { return false; } } @Override public int hashCode() { return this.x + this.z << 8 + this.y << 16; } @Override public int compareTo(IntVector3 other) { return this.y == other.y ? (this.z == other.z ? this.x - other.x : this.z - other.z) : this.y - other.y; } public IntVector3 subtract(int x, int y, int z) { return new IntVector3(this.x - x, this.y - y, this.z - z); } public IntVector3 subtract(IntVector3 other) { return subtract(other.x, other.y, other.z); } public IntVector3 subtract(BlockFace face, int length) { return subtract(face.getModX() * length, face.getModY() * length, face.getModZ() * length); } public IntVector3 subtract(BlockFace face) { return subtract(face.getModX(), face.getModY(), face.getModZ()); } public IntVector3 add(int x, int y, int z) { return new IntVector3(this.x + x, this.y + y, this.z + z); } public IntVector3 add(IntVector3 other) { return add(other.x, other.y, other.z); } public IntVector3 add(BlockFace face, int length) { return add(face.getModX() * length, face.getModY() * length, face.getModZ() * length); } public IntVector3 add(BlockFace face) { return add(face.getModX(), face.getModY(), face.getModZ()); } public IntVector3 multiply(int x, int y, int z) { return new IntVector3(this.x * x, this.y * y, this.z * z); } public IntVector3 multiply(double x, double y, double z) { return new IntVector3((double) this.x * x, (double) this.y * y, (double) this.z * z); } public IntVector3 multiply(int factor) { return multiply(factor, factor, factor); } public IntVector3 multiply(double factor) { return multiply(factor, factor, factor); } public IntVector3 multiply(IntVector3 other) { return multiply(other.x, other.y, other.z); } public IntVector3 abs() { return new IntVector3(Math.abs(x), Math.abs(y), Math.abs(z)); } /** * Checks whether the x, y or z coordinate is greater than the value specified * * @param value to check * @return True if x/y/z > value, False otherwise */ public boolean greaterThan(int value) { return x > value || y > value || z > value; } /** * Checks whether the x, y or z coordinate is greater/equal than the value specified * * @param value to check * @return True if x/y/z >= value, False otherwise */ public boolean greaterEqualThan(int value) { return x >= value || y >= value || z >= value; } public int getChunkX() { return x >> 4; } public int getChunkY() { return y >> 4; } public int getChunkZ() { return z >> 4; } /** * Gets the block at the coordinates of this IntVector3 on the world * specified * * @param world * to get a block of * @return block at the world */ public Block toBlock(World world) { return world.getBlockAt(x, y, z); } /** * Obtains the chunk coordinates, treating this IntVector3 as block * coordinates * * @return chunk coordinates */ public IntVector2 toChunkCoordinates() { return new IntVector2(getChunkX(), getChunkZ()); } /** * Gets the X-coordinate of the middle of 'the' block * * @return block middle X */ public double midX() { return (double) x + 0.5; } /** * Gets the Y-coordinate of the middle of 'the' block * * @return block middle Y */ public double midY() { return (double) y + 0.5; } /** * Gets the Z-coordinate of the middle of 'the' block * * @return block middle Z */ public double midZ() { return (double) z + 0.5; } /** * Converts this IntVector3 into an IntVector2 using the x/z coordinates * * @return new IntVector2 */ public IntVector2 toIntVector2() { return new IntVector2(x, z); } public static IntVector3 read(DataInputStream stream) throws IOException { return new IntVector3(stream.readInt(), stream.readInt(), stream.readInt()); } public void write(DataOutputStream stream) throws IOException { stream.writeInt(this.x); stream.writeInt(this.y); stream.writeInt(this.z); } }