blob: 60ece17c9a4681b569dcbb2f4dd6e7577bf2dbb3 [file] [log] [blame] [raw]
package universalelectricity.prefab;
import net.minecraft.src.ChunkCoordinates;
import net.minecraft.src.Entity;
import net.minecraft.src.MathHelper;
import net.minecraft.src.MovingObjectPosition;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.TileEntity;
import net.minecraft.src.Vec3;
import net.minecraft.src.World;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.implement.IConnector;
/**
* Vector3 Class is used for defining objects in a 3D space. Vector3 makes it easier to handle the coordinates of objects. Instead of
* fumbling with x, y and z variables, all x, y and z variables are stored in one class. Vector3.x, Vector3.y, Vector3.z.
* @author Calclavia
*/
public class Vector3 extends Vector2 implements Cloneable
{
public double z;
public static final Vector3[] side = {new Vector3(0, -1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, -1), new Vector3(0, 0, 1), new Vector3(-1, 0, 0), new Vector3(1, 0, 0)};
public Vector3()
{
this(0, 0, 0);
}
public Vector3(int x, int y, int z)
{
this.x = x;
this.y = y;
this.z = z;
}
public Vector3(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
/**
* Returns the coordinates as integers
*/
public int intX()
{
return (int)Math.floor(this.x);
}
public int intY()
{
return (int)Math.floor(this.y);
}
public int intZ()
{
return (int)Math.floor(this.z);
}
/**
* Makes a new copy of this Vector. Prevents variable referencing problems.
*/
@Override
public Vector3 clone()
{
return new Vector3(this.x, this.y, this.z);
}
/**
* Converts a TileEntity's position into Vector3
*/
public static Vector3 get(Entity par1)
{
return new Vector3(par1.posX, par1.posY, par1.posZ);
}
/**
* Converts an entity's position into Vector3
*/
public static Vector3 get(TileEntity par1)
{
return new Vector3(par1.xCoord, par1.yCoord, par1.zCoord);
}
/**
* Converts from Vec3 into a Vector3
*/
public static Vector3 get(Vec3 par1)
{
return new Vector3(par1.xCoord, par1.yCoord, par1.zCoord);
}
/**
* Converts a MovingObjectPosition to Vector3
*/
public static Vector3 get(MovingObjectPosition par1)
{
return new Vector3(par1.blockX, par1.blockY, par1.blockZ);
}
/**
* Converts a MovingObjectPosition to Vector3
*/
public static Vector3 get(ChunkCoordinates par1)
{
return new Vector3(par1.posX, par1.posY, par1.posZ);
}
public int getBlockID(World world)
{
return world.getBlockId(this.intX(), this.intY(), this.intZ());
}
public int getBlockMetadata(World world)
{
return world.getBlockMetadata(this.intX(), this.intY(), this.intZ());
}
public TileEntity getTileEntity(World world)
{
return world.getBlockTileEntity(this.intX(), this.intY(), this.intZ());
}
public void setBlock(World world, int id, int metadata)
{
world.setBlockAndMetadata(this.intX(), this.intY(), this.intZ(), id, metadata);
}
public void setBlock(World world, int id)
{
world.setBlock(this.intX(), this.intY(), this.intZ(), id);
}
public void setBlockWithNotify(World world, int id, int metadata)
{
world.setBlockAndMetadataWithNotify(this.intX(), this.intY(), this.intZ(), id, metadata);
}
public void setBlockWithNotify(World world, int id)
{
world.setBlockWithNotify(this.intX(), this.intY(), this.intZ(), id);
}
/**
* Converts this Vector3 into a Vector2 by dropping the Y axis.
*/
public Vector2 toVector2()
{
return new Vector2(this.x, this.z);
}
/**
* Converts this vector three into a Minecraft Vec3 object
*/
public Vec3 toVec3()
{
return Vec3.createVectorHelper(this.x, this.y, this.z);
}
/**
* Checks if a Vector3 point is located inside a region
*/
public static boolean isPointInRegion(Vector3 point, Vector3 minPoint, Vector3 maxPoint)
{
return (point.x > minPoint.x && point.x < maxPoint.x) && (point.y > minPoint.y && point.y < maxPoint.y) && (point.z > minPoint.z && point.z < maxPoint.z);
}
/**
* Compares two vectors and see if they are equal. True if so.
*/
public boolean isEqual(Vector3 vector3)
{
return (this.x == vector3.x && this.y == vector3.y && this.z == vector3.z);
}
/**
* Gets the distance between two vectors
* @return The distance
*/
public static double distance(Vector3 par1, Vector3 par2)
{
double var2 = par1.x - par2.x;
double var4 = par1.y - par2.y;
double var6 = par1.z - par2.z;
return MathHelper.sqrt_double(var2 * var2 + var4 * var4 + var6 * var6);
}
public double distanceTo(Vector3 vector3)
{
double var2 = vector3.x - this.x;
double var4 = vector3.y - this.y;
double var6 = vector3.z - this.z;
return MathHelper.sqrt_double(var2 * var2 + var4 * var4 + var6 * var6);
}
public static Vector3 subtract(Vector3 par1, Vector3 par2)
{
return new Vector3(par1.x - par2.x, par1.y - par2.y, par1.z - par2.z);
}
public static Vector3 add(Vector3 par1, Vector3 par2)
{
return new Vector3(par1.x + par2.x, par1.y + par2.y, par1.z + par2.z);
}
public static Vector3 add(Vector3 par1, double par2)
{
return new Vector3(par1.x + par2, par1.y + par2, par1.z + par2);
}
public void add(Vector3 par1)
{
this.x += par1.x;
this.y += par1.y;
this.z += par1.z;
}
@Override
public void add(double par1)
{
this.x += par1;
this.y += par1;
this.z += par1;
}
public static Vector3 multiply(Vector3 par1, Vector3 par2)
{
return new Vector3(par1.x * par2.x, par1.y * par2.y, par1.z * par2.z);
}
public static Vector3 multiply(Vector3 par1, double par2)
{
return new Vector3(par1.x * par2, par1.y * par2, par1.z * par2);
}
public static Vector3 readFromNBT(String prefix, NBTTagCompound par1NBTTagCompound)
{
Vector3 tempVector = new Vector3();
tempVector.x = par1NBTTagCompound.getDouble(prefix + "X");
tempVector.y = par1NBTTagCompound.getDouble(prefix + "Y");
tempVector.z = par1NBTTagCompound.getDouble(prefix + "Z");
return tempVector;
}
/**
* Saves this Vector3 to disk
* @param prefix - The prefix of this save. Use some unique string.
* @param par1NBTTagCompound - The NBT compound object to save the data in
*/
public void writeToNBT(String prefix, NBTTagCompound par1NBTTagCompound)
{
par1NBTTagCompound.setDouble(prefix + "X", this.x);
par1NBTTagCompound.setDouble(prefix + "Y", this.y);
par1NBTTagCompound.setDouble(prefix + "Z", this.z);
}
@Override
public Vector3 round()
{
return new Vector3(Math.round(this.x), Math.round(this.y), Math.round(this.z));
}
@Override
public Vector3 floor()
{
return new Vector3(Math.floor(this.x), Math.floor(this.y), Math.floor(this.z));
}
public Vector3 top()
{
return add(this, side[0]);
}
public Vector3 bottom()
{
return add(this, side[1]);
}
public Vector3 front()
{
return add(this, side[2]);
}
public Vector3 back()
{
return add(this, side[3]);
}
public Vector3 left()
{
return add(this, side[4]);
}
public Vector3 right()
{
return add(this, side[5]);
}
@Override
public String output()
{
return "Vector3: " + this.x + "," + this.y + "," + this.z;
}
/**
* Gets a position relative to another position's side
* @param position - The position
* @param side - The side. 0-5
* @return The position relative to the original position's side
*/
public void modifyPositionFromSide(ForgeDirection side)
{
switch (side.ordinal())
{
case 0: this.y -= 1; break;
case 1: this.y += 1; break;
case 2: this.z -= 1; break;
case 3: this.z += 1; break;
case 4: this.x -= 1; break;
case 5: this.x += 1; break;
}
}
public static TileEntity getTileEntityFromSide(World world, Vector3 position, ForgeDirection side)
{
position.modifyPositionFromSide(side);
return world.getBlockTileEntity(position.intX(), position.intY(), position.intZ());
}
/**
* Gets a connector unit based on the given side.
*/
public static TileEntity getConnectorFromSide(World world, Vector3 position, ForgeDirection side)
{
TileEntity tileEntity = getTileEntityFromSide(world, position, side);
if (tileEntity instanceof IConnector)
{
if (((IConnector)tileEntity).canConnect(getOrientationFromSide(side, ForgeDirection.NORTH)))
{
return tileEntity;
}
}
return null;
}
/**
* Finds the side of a block depending on it's facing direction from the given side.
* The side numbers are compatible with the function"getBlockTextureFromSideAndMetadata".
*
* Bottom: 0;
* Top: 1;
* Back: 2;
* Front: 3;
* Left: 4;
* Right: 5;
* @param front - The direction in which this block is facing/front. Use a number between 0 and 5. Default is 3.
* @param side - The side you are trying to find. A number between 0 and 5.
* @return The side relative to the facing direction.
*/
public static ForgeDirection getOrientationFromSide(ForgeDirection front, ForgeDirection side)
{
switch (front.ordinal())
{
case 0:
switch (side.ordinal())
{
case 0: return ForgeDirection.getOrientation(3);
case 1: return ForgeDirection.getOrientation(2);
case 2: return ForgeDirection.getOrientation(1);
case 3: return ForgeDirection.getOrientation(0);
case 4: return ForgeDirection.getOrientation(5);
case 5: return ForgeDirection.getOrientation(4);
}
case 1:
switch (side.ordinal())
{
case 0: return ForgeDirection.getOrientation(4);
case 1: return ForgeDirection.getOrientation(5);
case 2: return ForgeDirection.getOrientation(0);
case 3: return ForgeDirection.getOrientation(1);
case 4: return ForgeDirection.getOrientation(2);
case 5: return ForgeDirection.getOrientation(3);
}
case 2:
switch (side.ordinal())
{
case 0: return ForgeDirection.getOrientation(0);
case 1: return ForgeDirection.getOrientation(1);
case 2: return ForgeDirection.getOrientation(3);
case 3: return ForgeDirection.getOrientation(2);
case 4: return ForgeDirection.getOrientation(5);
case 5: return ForgeDirection.getOrientation(4);
}
case 3:
return side;
case 4:
switch (side.ordinal())
{
case 0: return ForgeDirection.getOrientation(0);
case 1: return ForgeDirection.getOrientation(1);
case 2: return ForgeDirection.getOrientation(5);
case 3: return ForgeDirection.getOrientation(4);
case 4: return ForgeDirection.getOrientation(3);
case 5: return ForgeDirection.getOrientation(2);
}
case 5:
switch (side.ordinal())
{
case 0: return ForgeDirection.getOrientation(0);
case 1: return ForgeDirection.getOrientation(1);
case 2: return ForgeDirection.getOrientation(4);
case 3: return ForgeDirection.getOrientation(5);
case 4: return ForgeDirection.getOrientation(2);
case 5: return ForgeDirection.getOrientation(3);
}
}
return ForgeDirection.UNKNOWN;
}
}