package mods.eln.misc;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Vec3;
import net.minecraftforge.common.util.ForgeDirection;
import org.lwjgl.opengl.GL11;
/**
* Represents the 6 possible directions along the axis of a block.
*/
public enum Direction {
/**
* -X
*/
XN(0),
/**
* +X
*/
XP(1),
/**
* -Y
*/
YN(2), //MC-Code starts with 0 here
/**
* +Y
*/
YP(3), // 1...
/**
* -Z
*/
ZN(4),
/**
* +Z
*/
ZP(5);
static final Direction[] intToDir = {XN, XP, YN, YP, ZN, ZP};
int dir;
Direction(int dir) {
this.dir = dir;
}
public int getInt() {
return dir;
}
public boolean isNotY() {
return this != YP && this != YN;
}
public boolean isY() {
return this == YP || this == YN;
}
public void applyTo(double[] vector, double distance) {
if (dir == 0) vector[0] -= distance;
if (dir == 1) vector[0] += distance;
if (dir == 2) vector[1] -= distance;
if (dir == 3) vector[1] += distance;
if (dir == 4) vector[2] -= distance;
if (dir == 5) vector[2] += distance;
}
public void applyTo(int[] vector, int distance) {
if (dir == 0) vector[0] -= distance;
if (dir == 1) vector[0] += distance;
if (dir == 2) vector[1] -= distance;
if (dir == 3) vector[1] += distance;
if (dir == 4) vector[2] -= distance;
if (dir == 5) vector[2] += distance;
}
public int getHorizontalIndex() {
switch (this) {
case XN:
return 0;
case XP:
return 1;
case YN:
return 0;
case YP:
return 0;
case ZN:
return 2;
case ZP:
return 3;
default:
return 0;
}
}
public static Direction fromHorizontalIndex(int nbr) {
switch (nbr) {
case 0:
return XN;
case 1:
return XP;
case 2:
return ZN;
case 3:
return ZP;
default:
return XN;
}
}
/*public CoordinateTuple ApplyToCoordinates(CoordinateTuple coordinates) {
CoordinateTuple ret = new CoordinateTuple(coordinates);
ret.coords[dir / 2] += GetSign();
return ret;
}*/
/**
* Get the tile entity next to a tile entity following this direction.
*
* @param tileEntity tile entity to check
* @return Adjacent tile entity or null if none exists
*/
public TileEntity applyToTileEntity(TileEntity tileEntity) {
if (tileEntity == null) return null;
int coords[] = {tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord};
coords[dir / 2] += getSign();
if (tileEntity.getWorldObj() != null && tileEntity.getWorldObj().blockExists(coords[0], coords[1], coords[2])) {
return tileEntity.getWorldObj().getTileEntity(coords[0], coords[1], coords[2]);
} else {
return null;
}
}
public TileEntity applyToTileEntityAndSameClassThan(TileEntity tileEntity, Class c) {
if (tileEntity == null) return null;
TileEntity findedEntity = applyToTileEntity(tileEntity);
if (findedEntity == null) return null;
if (!Utils.isTheClass(findedEntity, c)) return null;
return findedEntity;
}
/**
* Get the inverse of this direction (XN -> XP, XP -> XN, etc.)
*
* @return Inverse direction
*/
public Direction getInverse() {
int inverseDir = dir - getSign();
for (Direction direction : Direction.values()) {
if (direction.dir == inverseDir) return direction;
}
return this;
}
/**
* Convert this direction to a Minecraft side value.
*
* @return Minecraft side value
*/
public int toSideValue() {
return (dir + 4) % 6;
}
/**
* Determine direction sign (N for negative or P for positive).
*
* @return -1 if the direction is negative, +1 if the direction is positive
*/
private int getSign() {
return (dir % 2) * 2 - 1;
}
public void renderBlockFace(int x, int y, float spriteDim) {
switch (this) {
case XN:
GL11.glNormal3f(-1.0f, 0.0f, 0.0f);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(-0.5F, 0.5F, 0.5f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(-0.5F, 0.5F, -0.5f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(-0.5F, -0.5F, -0.5f);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(-0.5F, -0.5F, 0.5f);
break;
case XP:
GL11.glNormal3f(1.0f, 0.0f, 0.0f);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(0.5F, 0.5F, -0.5f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(0.5F, 0.5F, 0.5f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(0.5F, -0.5F, 0.5f);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(0.5F, -0.5F, -0.5f);
break;
case YN:
GL11.glNormal3f(0.0f, -1.0f, 0.0f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(0.5F, -0.5f, -0.5F);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(0.5F, -0.5f, 0.5F);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(-0.5F, -0.5f, 0.5F);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(-0.5F, -0.5f, -0.5F);
break;
case YP:
GL11.glNormal3f(0.0f, 1.0f, 0.0f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(-0.5F, 0.5f, -0.5F);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(-0.5F, 0.5f, 0.5F);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(0.5F, 0.5f, 0.5F);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(0.5F, 0.5f, -0.5F);
break;
case ZN:
GL11.glNormal3f(0.0f, 0.0f, -1.0f);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(-0.5F, 0.5F, -0.5f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(0.5F, 0.5F, -0.5f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(0.5F, -0.5F, -0.5f);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(-0.5F, -0.5F, -0.5f);
break;
case ZP:
GL11.glNormal3f(0.0f, 0.0f, 1.0f);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(0.5F, 0.5F, 0.5f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 0) * spriteDim);
GL11.glVertex3f(-0.5F, 0.5F, 0.5f);
GL11.glTexCoord2f((x + 0) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(-0.5F, -0.5F, 0.5f);
GL11.glTexCoord2f((x + 1) * spriteDim, (y + 1) * spriteDim);
GL11.glVertex3f(0.5F, -0.5F, 0.5f);
break;
default:
break;
}
}
static public Direction fromInt(int idx) {
for (Direction direction : Direction.values()) {
if (direction.dir == idx) return direction;
}
return null;
}
static public Direction fromIntMinecraftSide(int idx) {
idx = (idx + 2) % 6;
for (Direction direction : Direction.values()) {
if (direction.dir == idx) return direction;
}
return null;
}
public Direction right() {
switch (this) {
case XN:
return ZP;
case XP:
return ZN;
case YN:
return ZN;
case YP:
return ZP;
case ZN:
return XN;
case ZP:
return XP;
}
return null;
}
public Direction left() {
return right().getInverse();
}
public Direction up() {
switch (this) {
case XN:
return YP;
case XP:
return YP;
case YN:
return XP;
case YP:
return XP;
case ZN:
return YP;
case ZP:
return YP;
}
return null;
}
public Direction down() {
return up().getInverse();
}
public Direction back() {
return getInverse();
}
public Direction applyLRDU(LRDU lrdu) {
switch (lrdu) {
case Down:
return this.down();
case Left:
return this.left();
case Right:
return this.right();
case Up:
return this.up();
default:
break;
}
return null;
}
public LRDU getLRDUGoingTo(Direction target) {
for (LRDU lrdu : LRDU.values()) {
if (target == applyLRDU(lrdu)) return lrdu;
}
return null;
}
public void glRotateXnRef() {
//toCheck
switch (this) {
case XN:
break;
case XP:
//GL11.glScalef(-1f, 1, -1f);
GL11.glRotatef(180, 0f, 1f, 0f);
break;
case YN:
GL11.glRotatef(90f, 0f, 0f, 1f);
GL11.glScalef(1f, -1f, -1f);
break;
case YP:
GL11.glRotatef(90f, 0f, 0f, -1f);
break;
case ZN:
GL11.glRotatef(270f, 0f, 1f, 0f);
break;
case ZP:
GL11.glRotatef(90f, 0f, 1f, 0f);
break;
default:
break;
}
}
public void glRotateXnRefInv() {
//toCheck
switch (this) {
case XN:
break;
case XP:
//GL11.glScalef(-1f, 1, -1f);
GL11.glRotatef(180, 0f, -1f, 0f);
break;
case YN:
GL11.glScalef(1f, -1f, -1f);
GL11.glRotatef(90f, 0f, 0f, -1f);
break;
case YP:
GL11.glRotatef(90f, 0f, 0f, 1f);
break;
case ZN:
GL11.glRotatef(270f, 0f, -1f, 0f);
break;
case ZP:
GL11.glRotatef(90f, 0f, -1f, 0f);
break;
default:
break;
}
}
public void glRotateZnRef() {
//toCheck
switch (this) {
case XN:
GL11.glRotatef(90f, 0f, 1f, 0f);
break;
case XP:
GL11.glRotatef(90f, 0f, -1f, 0f);
break;
case YN:
GL11.glRotatef(90f, 1f, 0f, 0f);
GL11.glScalef(1f, -1, 1f);
break;
case YP:
GL11.glRotatef(90f, 1f, 0f, 0f);
GL11.glScalef(1f, 1f, 1f);
break;
case ZN:
//GL11.glRotatef(90f, 0f, -1f, 0f);
break;
case ZP:
GL11.glRotatef(180f, 0f, 1f, 0f);
break;
default:
break;
}
}
public TileEntity getTileEntity(Coordonate coordonate) {
int x = coordonate.x, y = coordonate.y, z = coordonate.z;
switch (this) {
case XN:
x--;
break;
case XP:
x++;
break;
case YN:
y--;
break;
case YP:
y++;
break;
case ZN:
z--;
break;
case ZP:
z++;
break;
default:
break;
}
return coordonate.world().getTileEntity(x, y, z);
}
public void writeToNBT(NBTTagCompound nbt, String name) {
nbt.setByte(name, (byte) getInt());
}
static public Direction readFromNBT(NBTTagCompound nbt, String name) {
return Direction.fromInt(nbt.getByte(name));
}
public void rotateFromXN(double[] p) {
double x = p[0], y = p[1], z = p[2];
switch (this) {
case XN:
break;
case XP:
p[0] = -x;
p[2] = -z;
break;
case YN:
p[0] = y;
p[1] = x;
p[2] = -z;
break;
case YP:
p[0] = y;
p[1] = -x;
p[2] = z;
break;
case ZN:
p[0] = -z;
p[2] = x;
break;
case ZP:
p[0] = z;
p[2] = -x;
break;
default:
break;
}
}
public void rotateFromXN(int[] p) {
int x = p[0], y = p[1], z = p[2];
switch (this) {
case XN:
break;
case XP:
p[0] = -x;
p[2] = -z;
break;
case YN:
p[0] = y;
p[1] = x;
p[2] = -z;
break;
case YP:
p[0] = y;
p[1] = -x;
p[2] = z;
break;
case ZN:
p[0] = -z;
p[2] = x;
break;
case ZP:
p[0] = z;
p[2] = -x;
break;
default:
break;
}
}
public void rotateFromXN(Vec3 p) {
double x = p.xCoord, y = p.yCoord, z = p.zCoord;
switch (this) {
case XN:
break;
case XP:
p.xCoord = -x;
p.zCoord = -z;
break;
case YN:
p.xCoord = y;
p.yCoord = x;
p.zCoord = -z;
break;
case YP:
p.xCoord = y;
p.yCoord = -x;
p.zCoord = z;
break;
case ZN:
p.xCoord = -z;
p.zCoord = x;
break;
case ZP:
p.xCoord = z;
p.zCoord = -x;
break;
default:
break;
}
}
public void rotateFromXN(Coordonate p) {
int x = p.x, y = p.y, z = p.z;
switch (this) {
case XN:
break;
case XP:
p.x = -x;
p.z = -z;
break;
case YN:
p.x = y;
p.y = x;
p.z = -z;
break;
case YP:
p.x = y;
p.y = -x;
p.z = z;
break;
case ZN:
p.x = -z;
p.z = x;
break;
case ZP:
p.x = z;
p.z = -x;
break;
default:
break;
}
}
public void glTranslate(float v) {
switch (this) {
case XN:
GL11.glTranslatef(-v, 0f, 0f);
break;
case XP:
GL11.glTranslatef(v, 0f, 0f);
break;
case YN:
GL11.glTranslatef(0f, -v, 0f);
break;
case YP:
GL11.glTranslatef(0f, v, 0f);
break;
case ZN:
GL11.glTranslatef(0f, 0f, -v);
break;
case ZP:
GL11.glTranslatef(0f, 0f, v);
break;
default:
break;
}
}
public static Direction from(ForgeDirection direction) {
switch (direction) {
case DOWN:
return YN;
case EAST:
return XP;
case NORTH:
return ZN;
case SOUTH:
return ZP;
case UP:
return YP;
case WEST:
return XN;
default:
return YN;
}
}
public ForgeDirection toForge() {
switch (this) {
case YN:
return ForgeDirection.DOWN;
case XP:
return ForgeDirection.EAST;
case ZN:
return ForgeDirection.NORTH;
case ZP:
return ForgeDirection.SOUTH;
case YP:
return ForgeDirection.UP;
case XN:
return ForgeDirection.WEST;
default:
return ForgeDirection.UNKNOWN;
}
}
public void glRotateZnRefInv() {
switch (this) {
case XN:
GL11.glRotatef(-90f, 0f, 1f, 0f);
break;
case XP:
GL11.glRotatef(-90f, 0f, -1f, 0f);
break;
case YN:
GL11.glRotatef(-90f, 1f, 0f, 0f);
GL11.glScalef(1f, -1, 1f);
break;
case YP:
GL11.glRotatef(-90f, 1f, 0f, 0f);
GL11.glScalef(1f, 1f, 1f);
break;
case ZN:
//GL11.glRotatef(90f, 0f, -1f, 0f);
break;
case ZP:
GL11.glRotatef(-180f, 0f, 1f, 0f);
break;
default:
break;
}
}
}