tcr/java/src/game/world/Facing.java

494 lines
13 KiB
Java
Raw Normal View History

2025-03-11 00:23:54 +01:00
package game.world;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Predicate;
import game.ExtMath;
import game.collect.Iterators;
import game.collect.Maps;
import game.properties.IStringSerializable;
import game.rng.Random;
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 test(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 test(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());
}
}
}