494 lines
13 KiB
Java
Executable file
494 lines
13 KiB
Java
Executable file
package game.world;
|
|
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
|
|
import com.google.common.base.Predicate;
|
|
import com.google.common.collect.Iterators;
|
|
import com.google.common.collect.Maps;
|
|
|
|
import game.properties.IStringSerializable;
|
|
import game.rng.Random;
|
|
import game.util.ExtMath;
|
|
|
|
public enum Facing implements IStringSerializable
|
|
{
|
|
DOWN(0, 2, 1, -1, "down", Facing.AxisDirection.NEGATIVE, Facing.Axis.Y, new Vec3i(0, -1, 0)),
|
|
UP(1, 3, 0, -1, "up", Facing.AxisDirection.POSITIVE, Facing.Axis.Y, new Vec3i(0, 1, 0)),
|
|
NORTH(2, 4, 3, 2, "north", Facing.AxisDirection.NEGATIVE, Facing.Axis.Z, new Vec3i(0, 0, -1)),
|
|
SOUTH(3, 5, 2, 0, "south", Facing.AxisDirection.POSITIVE, Facing.Axis.Z, new Vec3i(0, 0, 1)),
|
|
WEST(4, 1, 5, 1, "west", Facing.AxisDirection.NEGATIVE, Facing.Axis.X, new Vec3i(-1, 0, 0)),
|
|
EAST(5, 0, 4, 3, "east", Facing.AxisDirection.POSITIVE, Facing.Axis.X, new Vec3i(1, 0, 0));
|
|
|
|
/** Ordering index for D-U-N-S-W-E */
|
|
private final int index;
|
|
private final int qindex;
|
|
|
|
/** Index of the opposite Facing in the VALUES array */
|
|
private final int opposite;
|
|
|
|
/** Ordering index for the HORIZONTALS field (S-W-N-E) */
|
|
private final int horizontalIndex;
|
|
private final String name;
|
|
private final Facing.Axis axis;
|
|
private final Facing.AxisDirection axisDirection;
|
|
|
|
/** Normalized Vector that points in the direction of this Facing */
|
|
private final Vec3i directionVec;
|
|
|
|
/** All facings in D-U-N-S-W-E order */
|
|
private static final Facing[] VALUES = new Facing[6];
|
|
|
|
/** All Facings with horizontal axis in order S-W-N-E */
|
|
private static final Facing[] HORIZONTALS = new Facing[4];
|
|
private static final Map<String, Facing> NAME_LOOKUP = Maps.<String, Facing>newHashMap();
|
|
|
|
private Facing(int indexIn, int qindexIn, int oppositeIn, int horizontalIndexIn, String nameIn, Facing.AxisDirection axisDirectionIn, Facing.Axis axisIn, Vec3i directionVecIn)
|
|
{
|
|
this.index = indexIn;
|
|
this.qindex = qindexIn;
|
|
this.horizontalIndex = horizontalIndexIn;
|
|
this.opposite = oppositeIn;
|
|
this.name = nameIn;
|
|
this.axis = axisIn;
|
|
this.axisDirection = axisDirectionIn;
|
|
this.directionVec = directionVecIn;
|
|
}
|
|
|
|
/**
|
|
* Get the Index of this Facing (0-5). The order is D-U-N-S-W-E
|
|
*/
|
|
public int getIndex()
|
|
{
|
|
return this.index;
|
|
}
|
|
|
|
public int getQIndex()
|
|
{
|
|
return this.qindex;
|
|
}
|
|
|
|
/**
|
|
* Get the index of this horizontal facing (0-3). The order is S-W-N-E
|
|
*/
|
|
public int getHorizontalIndex()
|
|
{
|
|
return this.horizontalIndex;
|
|
}
|
|
|
|
/**
|
|
* Get the AxisDirection of this Facing.
|
|
*/
|
|
public Facing.AxisDirection getAxisDirection()
|
|
{
|
|
return this.axisDirection;
|
|
}
|
|
|
|
/**
|
|
* Get the opposite Facing (e.g. DOWN => UP)
|
|
*/
|
|
public Facing getOpposite()
|
|
{
|
|
return getFront(this.opposite);
|
|
}
|
|
|
|
/**
|
|
* Rotate this Facing around the given axis clockwise. If this facing cannot be rotated around the given axis,
|
|
* returns this facing without rotating.
|
|
*/
|
|
public Facing rotateAround(Facing.Axis axis)
|
|
{
|
|
switch (axis)
|
|
{
|
|
case X:
|
|
if (this != WEST && this != EAST)
|
|
{
|
|
return this.rotateX();
|
|
}
|
|
|
|
return this;
|
|
|
|
case Y:
|
|
if (this != UP && this != DOWN)
|
|
{
|
|
return this.rotateY();
|
|
}
|
|
|
|
return this;
|
|
|
|
case Z:
|
|
if (this != NORTH && this != SOUTH)
|
|
{
|
|
return this.rotateZ();
|
|
}
|
|
|
|
return this;
|
|
|
|
default:
|
|
throw new IllegalStateException("Unable to get CW facing for axis " + axis);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rotate this Facing around the Y axis clockwise (NORTH => EAST => SOUTH => WEST => NORTH)
|
|
*/
|
|
public Facing rotateY()
|
|
{
|
|
switch (this)
|
|
{
|
|
case NORTH:
|
|
return EAST;
|
|
|
|
case EAST:
|
|
return SOUTH;
|
|
|
|
case SOUTH:
|
|
return WEST;
|
|
|
|
case WEST:
|
|
return NORTH;
|
|
|
|
default:
|
|
throw new IllegalStateException("Unable to get Y-rotated facing of " + this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rotate this Facing around the X axis (NORTH => DOWN => SOUTH => UP => NORTH)
|
|
*/
|
|
private Facing rotateX()
|
|
{
|
|
switch (this)
|
|
{
|
|
case NORTH:
|
|
return DOWN;
|
|
|
|
case EAST:
|
|
case WEST:
|
|
default:
|
|
throw new IllegalStateException("Unable to get X-rotated facing of " + this);
|
|
|
|
case SOUTH:
|
|
return UP;
|
|
|
|
case UP:
|
|
return NORTH;
|
|
|
|
case DOWN:
|
|
return SOUTH;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rotate this Facing around the Z axis (EAST => DOWN => WEST => UP => EAST)
|
|
*/
|
|
private Facing rotateZ()
|
|
{
|
|
switch (this)
|
|
{
|
|
case EAST:
|
|
return DOWN;
|
|
|
|
case SOUTH:
|
|
default:
|
|
throw new IllegalStateException("Unable to get Z-rotated facing of " + this);
|
|
|
|
case WEST:
|
|
return UP;
|
|
|
|
case UP:
|
|
return EAST;
|
|
|
|
case DOWN:
|
|
return WEST;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Rotate this Facing around the Y axis counter-clockwise (NORTH => WEST => SOUTH => EAST => NORTH)
|
|
*/
|
|
public Facing rotateYCCW()
|
|
{
|
|
switch (this)
|
|
{
|
|
case NORTH:
|
|
return WEST;
|
|
|
|
case EAST:
|
|
return NORTH;
|
|
|
|
case SOUTH:
|
|
return EAST;
|
|
|
|
case WEST:
|
|
return SOUTH;
|
|
|
|
default:
|
|
throw new IllegalStateException("Unable to get CCW facing of " + this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a offset that addresses the block in front of this facing.
|
|
*/
|
|
public int getFrontOffsetX()
|
|
{
|
|
return this.axis == Facing.Axis.X ? this.axisDirection.getOffset() : 0;
|
|
}
|
|
|
|
public int getFrontOffsetY()
|
|
{
|
|
return this.axis == Facing.Axis.Y ? this.axisDirection.getOffset() : 0;
|
|
}
|
|
|
|
/**
|
|
* Returns a offset that addresses the block in front of this facing.
|
|
*/
|
|
public int getFrontOffsetZ()
|
|
{
|
|
return this.axis == Facing.Axis.Z ? this.axisDirection.getOffset() : 0;
|
|
}
|
|
|
|
/**
|
|
* Same as getName, but does not override the method from Enum.
|
|
*/
|
|
public String getName2()
|
|
{
|
|
return this.name;
|
|
}
|
|
|
|
public Facing.Axis getAxis()
|
|
{
|
|
return this.axis;
|
|
}
|
|
|
|
/**
|
|
* Get the facing specified by the given name
|
|
*/
|
|
public static Facing byName(String name)
|
|
{
|
|
return name == null ? null : (Facing)NAME_LOOKUP.get(name.toLowerCase());
|
|
}
|
|
|
|
/**
|
|
* Get a Facing by it's index (0-5). The order is D-U-N-S-W-E. Named getFront for legacy reasons.
|
|
*/
|
|
public static Facing getFront(int index)
|
|
{
|
|
return VALUES[ExtMath.absi(index % VALUES.length)];
|
|
}
|
|
|
|
/**
|
|
* Get a Facing by it's horizontal index (0-3). The order is S-W-N-E.
|
|
*/
|
|
public static Facing getHorizontal(int p_176731_0_)
|
|
{
|
|
return HORIZONTALS[ExtMath.absi(p_176731_0_ % HORIZONTALS.length)];
|
|
}
|
|
|
|
/**
|
|
* Get the Facing corresponding to the given angle (0-360). An angle of 0 is SOUTH, an angle of 90 would be WEST.
|
|
*/
|
|
public static Facing fromAngle(double angle)
|
|
{
|
|
return getHorizontal(ExtMath.floord(angle / 90.0D + 0.5D) & 3);
|
|
}
|
|
|
|
/**
|
|
* Choose a random Facing using the given Random
|
|
*/
|
|
public static Facing random(Random rand)
|
|
{
|
|
return values()[rand.zrange(values().length)];
|
|
}
|
|
|
|
public static Facing randHorizontal(Random rand)
|
|
{
|
|
return rand.pick(HORIZONTALS);
|
|
}
|
|
|
|
public static Facing getFacingFromVector(float p_176737_0_, float p_176737_1_, float p_176737_2_)
|
|
{
|
|
Facing enumfacing = NORTH;
|
|
float f = Float.MIN_VALUE;
|
|
|
|
for (Facing enumfacing1 : values())
|
|
{
|
|
float f1 = p_176737_0_ * (float)enumfacing1.directionVec.getX() + p_176737_1_ * (float)enumfacing1.directionVec.getY() + p_176737_2_ * (float)enumfacing1.directionVec.getZ();
|
|
|
|
if (f1 > f)
|
|
{
|
|
f = f1;
|
|
enumfacing = enumfacing1;
|
|
}
|
|
}
|
|
|
|
return enumfacing;
|
|
}
|
|
|
|
public String toString()
|
|
{
|
|
return this.name;
|
|
}
|
|
|
|
public String getName()
|
|
{
|
|
return this.name;
|
|
}
|
|
|
|
public static Facing getFacingFromAxis(Facing.AxisDirection p_181076_0_, Facing.Axis p_181076_1_)
|
|
{
|
|
for (Facing enumfacing : values())
|
|
{
|
|
if (enumfacing.getAxisDirection() == p_181076_0_ && enumfacing.getAxis() == p_181076_1_)
|
|
{
|
|
return enumfacing;
|
|
}
|
|
}
|
|
|
|
throw new IllegalArgumentException("No such direction: " + p_181076_0_ + " " + p_181076_1_);
|
|
}
|
|
|
|
/**
|
|
* Get a normalized Vector that points in the direction of this Facing.
|
|
*/
|
|
public Vec3i getDirectionVec()
|
|
{
|
|
return this.directionVec;
|
|
}
|
|
|
|
static {
|
|
for (Facing enumfacing : values())
|
|
{
|
|
VALUES[enumfacing.index] = enumfacing;
|
|
|
|
if (enumfacing.getAxis().isHorizontal())
|
|
{
|
|
HORIZONTALS[enumfacing.horizontalIndex] = enumfacing;
|
|
}
|
|
|
|
NAME_LOOKUP.put(enumfacing.getName2().toLowerCase(), enumfacing);
|
|
}
|
|
}
|
|
|
|
public static enum Axis implements Predicate<Facing>, IStringSerializable {
|
|
X("x", Facing.Plane.HORIZONTAL),
|
|
Y("y", Facing.Plane.VERTICAL),
|
|
Z("z", Facing.Plane.HORIZONTAL);
|
|
|
|
private static final Map<String, Facing.Axis> NAME_LOOKUP = Maps.<String, Facing.Axis>newHashMap();
|
|
private final String name;
|
|
private final Facing.Plane plane;
|
|
|
|
private Axis(String name, Facing.Plane plane)
|
|
{
|
|
this.name = name;
|
|
this.plane = plane;
|
|
}
|
|
|
|
public static Facing.Axis byName(String name)
|
|
{
|
|
return name == null ? null : (Facing.Axis)NAME_LOOKUP.get(name.toLowerCase());
|
|
}
|
|
|
|
public String getName2()
|
|
{
|
|
return this.name;
|
|
}
|
|
|
|
public boolean isVertical()
|
|
{
|
|
return this.plane == Facing.Plane.VERTICAL;
|
|
}
|
|
|
|
public boolean isHorizontal()
|
|
{
|
|
return this.plane == Facing.Plane.HORIZONTAL;
|
|
}
|
|
|
|
public String toString()
|
|
{
|
|
return this.name;
|
|
}
|
|
|
|
public boolean apply(Facing p_apply_1_)
|
|
{
|
|
return p_apply_1_ != null && p_apply_1_.getAxis() == this;
|
|
}
|
|
|
|
public Facing.Plane getPlane()
|
|
{
|
|
return this.plane;
|
|
}
|
|
|
|
public String getName()
|
|
{
|
|
return this.name;
|
|
}
|
|
|
|
static {
|
|
for (Facing.Axis enumfacing$axis : values())
|
|
{
|
|
NAME_LOOKUP.put(enumfacing$axis.getName2().toLowerCase(), enumfacing$axis);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static enum AxisDirection {
|
|
POSITIVE(1, "Towards positive"),
|
|
NEGATIVE(-1, "Towards negative");
|
|
|
|
private final int offset;
|
|
private final String description;
|
|
|
|
private AxisDirection(int offset, String description)
|
|
{
|
|
this.offset = offset;
|
|
this.description = description;
|
|
}
|
|
|
|
public int getOffset()
|
|
{
|
|
return this.offset;
|
|
}
|
|
|
|
public String toString()
|
|
{
|
|
return this.description;
|
|
}
|
|
}
|
|
|
|
public static enum Plane implements Predicate<Facing>, Iterable<Facing> {
|
|
HORIZONTAL,
|
|
VERTICAL;
|
|
|
|
public Facing[] facings()
|
|
{
|
|
switch (this)
|
|
{
|
|
case HORIZONTAL:
|
|
return new Facing[] {Facing.NORTH, Facing.EAST, Facing.SOUTH, Facing.WEST};
|
|
case VERTICAL:
|
|
return new Facing[] {Facing.UP, Facing.DOWN};
|
|
default:
|
|
throw new Error("Someone\'s been tampering with the universe!");
|
|
}
|
|
}
|
|
|
|
public Facing random(Random rand)
|
|
{
|
|
Facing[] aenumfacing = this.facings();
|
|
return aenumfacing[rand.zrange(aenumfacing.length)];
|
|
}
|
|
|
|
public boolean apply(Facing p_apply_1_)
|
|
{
|
|
return p_apply_1_ != null && p_apply_1_.getAxis().getPlane() == this;
|
|
}
|
|
|
|
public Iterator<Facing> iterator()
|
|
{
|
|
return Iterators.<Facing>forArray(this.facings());
|
|
}
|
|
}
|
|
}
|