704 lines
22 KiB
Java
704 lines
22 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* com.google.common.collect.ImmutableList
|
|
* com.google.common.collect.Iterators
|
|
* com.mojang.serialization.Codec
|
|
* com.mojang.serialization.DataResult
|
|
* io.netty.buffer.ByteBuf
|
|
* org.jetbrains.annotations.Contract
|
|
* org.joml.Matrix4fc
|
|
* org.joml.Quaternionf
|
|
* org.joml.Vector3f
|
|
* org.joml.Vector3fc
|
|
* org.jspecify.annotations.Nullable
|
|
*/
|
|
package net.minecraft.core;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.Iterators;
|
|
import com.mojang.serialization.Codec;
|
|
import com.mojang.serialization.DataResult;
|
|
import io.netty.buffer.ByteBuf;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Comparator;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.function.IntFunction;
|
|
import java.util.function.Predicate;
|
|
import java.util.stream.Stream;
|
|
import net.minecraft.core.Vec3i;
|
|
import net.minecraft.network.codec.ByteBufCodecs;
|
|
import net.minecraft.network.codec.StreamCodec;
|
|
import net.minecraft.util.ByIdMap;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.util.StringRepresentable;
|
|
import net.minecraft.util.Util;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import org.jetbrains.annotations.Contract;
|
|
import org.joml.Matrix4fc;
|
|
import org.joml.Quaternionf;
|
|
import org.joml.Vector3f;
|
|
import org.joml.Vector3fc;
|
|
import org.jspecify.annotations.Nullable;
|
|
|
|
public enum Direction implements StringRepresentable
|
|
{
|
|
DOWN(0, 1, -1, "down", AxisDirection.NEGATIVE, Axis.Y, new Vec3i(0, -1, 0)),
|
|
UP(1, 0, -1, "up", AxisDirection.POSITIVE, Axis.Y, new Vec3i(0, 1, 0)),
|
|
NORTH(2, 3, 2, "north", AxisDirection.NEGATIVE, Axis.Z, new Vec3i(0, 0, -1)),
|
|
SOUTH(3, 2, 0, "south", AxisDirection.POSITIVE, Axis.Z, new Vec3i(0, 0, 1)),
|
|
WEST(4, 5, 1, "west", AxisDirection.NEGATIVE, Axis.X, new Vec3i(-1, 0, 0)),
|
|
EAST(5, 4, 3, "east", AxisDirection.POSITIVE, Axis.X, new Vec3i(1, 0, 0));
|
|
|
|
public static final StringRepresentable.EnumCodec<Direction> CODEC;
|
|
public static final Codec<Direction> VERTICAL_CODEC;
|
|
public static final IntFunction<Direction> BY_ID;
|
|
public static final StreamCodec<ByteBuf, Direction> STREAM_CODEC;
|
|
@Deprecated
|
|
public static final Codec<Direction> LEGACY_ID_CODEC;
|
|
@Deprecated
|
|
public static final Codec<Direction> LEGACY_ID_CODEC_2D;
|
|
private static final ImmutableList<Axis> YXZ_AXIS_ORDER;
|
|
private static final ImmutableList<Axis> YZX_AXIS_ORDER;
|
|
private final int data3d;
|
|
private final int oppositeIndex;
|
|
private final int data2d;
|
|
private final String name;
|
|
private final Axis axis;
|
|
private final AxisDirection axisDirection;
|
|
private final Vec3i normal;
|
|
private final Vec3 normalVec3;
|
|
private final Vector3fc normalVec3f;
|
|
private static final Direction[] VALUES;
|
|
private static final Direction[] BY_3D_DATA;
|
|
private static final Direction[] BY_2D_DATA;
|
|
|
|
private Direction(int data3d, int oppositeIndex, int data2d, String name, AxisDirection axisDirection, Axis axis, Vec3i normal) {
|
|
this.data3d = data3d;
|
|
this.data2d = data2d;
|
|
this.oppositeIndex = oppositeIndex;
|
|
this.name = name;
|
|
this.axis = axis;
|
|
this.axisDirection = axisDirection;
|
|
this.normal = normal;
|
|
this.normalVec3 = Vec3.atLowerCornerOf(normal);
|
|
this.normalVec3f = new Vector3f((float)normal.getX(), (float)normal.getY(), (float)normal.getZ());
|
|
}
|
|
|
|
public static Direction[] orderedByNearest(Entity entity) {
|
|
Direction axisZ;
|
|
float pitch = entity.getViewXRot(1.0f) * ((float)Math.PI / 180);
|
|
float yaw = -entity.getViewYRot(1.0f) * ((float)Math.PI / 180);
|
|
float pitchSin = Mth.sin(pitch);
|
|
float pitchCos = Mth.cos(pitch);
|
|
float yawSin = Mth.sin(yaw);
|
|
float yawCos = Mth.cos(yaw);
|
|
boolean xPos = yawSin > 0.0f;
|
|
boolean yPos = pitchSin < 0.0f;
|
|
boolean zPos = yawCos > 0.0f;
|
|
float xYaw = xPos ? yawSin : -yawSin;
|
|
float yMag = yPos ? -pitchSin : pitchSin;
|
|
float zYaw = zPos ? yawCos : -yawCos;
|
|
float xMag = xYaw * pitchCos;
|
|
float zMag = zYaw * pitchCos;
|
|
Direction axisX = xPos ? EAST : WEST;
|
|
Direction axisY = yPos ? UP : DOWN;
|
|
Direction direction = axisZ = zPos ? SOUTH : NORTH;
|
|
if (xYaw > zYaw) {
|
|
if (yMag > xMag) {
|
|
return Direction.makeDirectionArray(axisY, axisX, axisZ);
|
|
}
|
|
if (zMag > yMag) {
|
|
return Direction.makeDirectionArray(axisX, axisZ, axisY);
|
|
}
|
|
return Direction.makeDirectionArray(axisX, axisY, axisZ);
|
|
}
|
|
if (yMag > zMag) {
|
|
return Direction.makeDirectionArray(axisY, axisZ, axisX);
|
|
}
|
|
if (xMag > yMag) {
|
|
return Direction.makeDirectionArray(axisZ, axisX, axisY);
|
|
}
|
|
return Direction.makeDirectionArray(axisZ, axisY, axisX);
|
|
}
|
|
|
|
private static Direction[] makeDirectionArray(Direction axis1, Direction axis2, Direction axis3) {
|
|
return new Direction[]{axis1, axis2, axis3, axis3.getOpposite(), axis2.getOpposite(), axis1.getOpposite()};
|
|
}
|
|
|
|
public static Direction rotate(Matrix4fc matrix, Direction facing) {
|
|
Vector3f vec = matrix.transformDirection(facing.normalVec3f, new Vector3f());
|
|
return Direction.getApproximateNearest(vec.x(), vec.y(), vec.z());
|
|
}
|
|
|
|
public static Collection<Direction> allShuffled(RandomSource random) {
|
|
return Util.shuffledCopy(Direction.values(), random);
|
|
}
|
|
|
|
public static Stream<Direction> stream() {
|
|
return Stream.of(VALUES);
|
|
}
|
|
|
|
public static float getYRot(Direction direction) {
|
|
return switch (direction.ordinal()) {
|
|
case 2 -> 180.0f;
|
|
case 3 -> 0.0f;
|
|
case 4 -> 90.0f;
|
|
case 5 -> -90.0f;
|
|
default -> throw new IllegalStateException("No y-Rot for vertical axis: " + String.valueOf(direction));
|
|
};
|
|
}
|
|
|
|
public Quaternionf getRotation() {
|
|
return switch (this.ordinal()) {
|
|
default -> throw new MatchException(null, null);
|
|
case 0 -> new Quaternionf().rotationX((float)Math.PI);
|
|
case 1 -> new Quaternionf();
|
|
case 2 -> new Quaternionf().rotationXYZ(1.5707964f, 0.0f, (float)Math.PI);
|
|
case 3 -> new Quaternionf().rotationX(1.5707964f);
|
|
case 4 -> new Quaternionf().rotationXYZ(1.5707964f, 0.0f, 1.5707964f);
|
|
case 5 -> new Quaternionf().rotationXYZ(1.5707964f, 0.0f, -1.5707964f);
|
|
};
|
|
}
|
|
|
|
public int get3DDataValue() {
|
|
return this.data3d;
|
|
}
|
|
|
|
public int get2DDataValue() {
|
|
return this.data2d;
|
|
}
|
|
|
|
public AxisDirection getAxisDirection() {
|
|
return this.axisDirection;
|
|
}
|
|
|
|
public static Direction getFacingAxis(Entity entity, Axis axis) {
|
|
return switch (axis.ordinal()) {
|
|
default -> throw new MatchException(null, null);
|
|
case 0 -> {
|
|
if (EAST.isFacingAngle(entity.getViewYRot(1.0f))) {
|
|
yield EAST;
|
|
}
|
|
yield WEST;
|
|
}
|
|
case 2 -> {
|
|
if (SOUTH.isFacingAngle(entity.getViewYRot(1.0f))) {
|
|
yield SOUTH;
|
|
}
|
|
yield NORTH;
|
|
}
|
|
case 1 -> entity.getViewXRot(1.0f) < 0.0f ? UP : DOWN;
|
|
};
|
|
}
|
|
|
|
public Direction getOpposite() {
|
|
return Direction.from3DDataValue(this.oppositeIndex);
|
|
}
|
|
|
|
public Direction getClockWise(Axis axis) {
|
|
return switch (axis.ordinal()) {
|
|
default -> throw new MatchException(null, null);
|
|
case 0 -> {
|
|
if (this == WEST || this == EAST) {
|
|
yield this;
|
|
}
|
|
yield this.getClockWiseX();
|
|
}
|
|
case 1 -> {
|
|
if (this == UP || this == DOWN) {
|
|
yield this;
|
|
}
|
|
yield this.getClockWise();
|
|
}
|
|
case 2 -> this == NORTH || this == SOUTH ? this : this.getClockWiseZ();
|
|
};
|
|
}
|
|
|
|
public Direction getCounterClockWise(Axis axis) {
|
|
return switch (axis.ordinal()) {
|
|
default -> throw new MatchException(null, null);
|
|
case 0 -> {
|
|
if (this == WEST || this == EAST) {
|
|
yield this;
|
|
}
|
|
yield this.getCounterClockWiseX();
|
|
}
|
|
case 1 -> {
|
|
if (this == UP || this == DOWN) {
|
|
yield this;
|
|
}
|
|
yield this.getCounterClockWise();
|
|
}
|
|
case 2 -> this == NORTH || this == SOUTH ? this : this.getCounterClockWiseZ();
|
|
};
|
|
}
|
|
|
|
public Direction getClockWise() {
|
|
return switch (this.ordinal()) {
|
|
case 2 -> EAST;
|
|
case 5 -> SOUTH;
|
|
case 3 -> WEST;
|
|
case 4 -> NORTH;
|
|
default -> throw new IllegalStateException("Unable to get Y-rotated facing of " + String.valueOf(this));
|
|
};
|
|
}
|
|
|
|
private Direction getClockWiseX() {
|
|
return switch (this.ordinal()) {
|
|
case 1 -> NORTH;
|
|
case 2 -> DOWN;
|
|
case 0 -> SOUTH;
|
|
case 3 -> UP;
|
|
default -> throw new IllegalStateException("Unable to get X-rotated facing of " + String.valueOf(this));
|
|
};
|
|
}
|
|
|
|
private Direction getCounterClockWiseX() {
|
|
return switch (this.ordinal()) {
|
|
case 1 -> SOUTH;
|
|
case 3 -> DOWN;
|
|
case 0 -> NORTH;
|
|
case 2 -> UP;
|
|
default -> throw new IllegalStateException("Unable to get X-rotated facing of " + String.valueOf(this));
|
|
};
|
|
}
|
|
|
|
private Direction getClockWiseZ() {
|
|
return switch (this.ordinal()) {
|
|
case 1 -> EAST;
|
|
case 5 -> DOWN;
|
|
case 0 -> WEST;
|
|
case 4 -> UP;
|
|
default -> throw new IllegalStateException("Unable to get Z-rotated facing of " + String.valueOf(this));
|
|
};
|
|
}
|
|
|
|
private Direction getCounterClockWiseZ() {
|
|
return switch (this.ordinal()) {
|
|
case 1 -> WEST;
|
|
case 4 -> DOWN;
|
|
case 0 -> EAST;
|
|
case 5 -> UP;
|
|
default -> throw new IllegalStateException("Unable to get Z-rotated facing of " + String.valueOf(this));
|
|
};
|
|
}
|
|
|
|
public Direction getCounterClockWise() {
|
|
return switch (this.ordinal()) {
|
|
case 2 -> WEST;
|
|
case 5 -> NORTH;
|
|
case 3 -> EAST;
|
|
case 4 -> SOUTH;
|
|
default -> throw new IllegalStateException("Unable to get CCW facing of " + String.valueOf(this));
|
|
};
|
|
}
|
|
|
|
public int getStepX() {
|
|
return this.normal.getX();
|
|
}
|
|
|
|
public int getStepY() {
|
|
return this.normal.getY();
|
|
}
|
|
|
|
public int getStepZ() {
|
|
return this.normal.getZ();
|
|
}
|
|
|
|
public Vector3f step() {
|
|
return new Vector3f(this.normalVec3f);
|
|
}
|
|
|
|
public String getName() {
|
|
return this.name;
|
|
}
|
|
|
|
public Axis getAxis() {
|
|
return this.axis;
|
|
}
|
|
|
|
public static @Nullable Direction byName(String name) {
|
|
return CODEC.byName(name);
|
|
}
|
|
|
|
public static Direction from3DDataValue(int data) {
|
|
return BY_3D_DATA[Mth.abs(data % BY_3D_DATA.length)];
|
|
}
|
|
|
|
public static Direction from2DDataValue(int data) {
|
|
return BY_2D_DATA[Mth.abs(data % BY_2D_DATA.length)];
|
|
}
|
|
|
|
public static Direction fromYRot(double yRot) {
|
|
return Direction.from2DDataValue(Mth.floor(yRot / 90.0 + 0.5) & 3);
|
|
}
|
|
|
|
public static Direction fromAxisAndDirection(Axis axis, AxisDirection direction) {
|
|
return switch (axis.ordinal()) {
|
|
default -> throw new MatchException(null, null);
|
|
case 0 -> {
|
|
if (direction == AxisDirection.POSITIVE) {
|
|
yield EAST;
|
|
}
|
|
yield WEST;
|
|
}
|
|
case 1 -> {
|
|
if (direction == AxisDirection.POSITIVE) {
|
|
yield UP;
|
|
}
|
|
yield DOWN;
|
|
}
|
|
case 2 -> direction == AxisDirection.POSITIVE ? SOUTH : NORTH;
|
|
};
|
|
}
|
|
|
|
public float toYRot() {
|
|
return (this.data2d & 3) * 90;
|
|
}
|
|
|
|
public static Direction getRandom(RandomSource random) {
|
|
return Util.getRandom(VALUES, random);
|
|
}
|
|
|
|
public static Direction getApproximateNearest(double dx, double dy, double dz) {
|
|
return Direction.getApproximateNearest((float)dx, (float)dy, (float)dz);
|
|
}
|
|
|
|
public static Direction getApproximateNearest(float dx, float dy, float dz) {
|
|
Direction result = NORTH;
|
|
float highestDot = Float.MIN_VALUE;
|
|
for (Direction direction : VALUES) {
|
|
float dot = dx * (float)direction.normal.getX() + dy * (float)direction.normal.getY() + dz * (float)direction.normal.getZ();
|
|
if (!(dot > highestDot)) continue;
|
|
highestDot = dot;
|
|
result = direction;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static Direction getApproximateNearest(Vec3 vec) {
|
|
return Direction.getApproximateNearest(vec.x, vec.y, vec.z);
|
|
}
|
|
|
|
@Contract(value="_,_,_,!null->!null;_,_,_,_->_")
|
|
public static @Nullable Direction getNearest(int x, int y, int z, @Nullable Direction orElse) {
|
|
int absX = Math.abs(x);
|
|
int absY = Math.abs(y);
|
|
int absZ = Math.abs(z);
|
|
if (absX > absZ && absX > absY) {
|
|
return x < 0 ? WEST : EAST;
|
|
}
|
|
if (absZ > absX && absZ > absY) {
|
|
return z < 0 ? NORTH : SOUTH;
|
|
}
|
|
if (absY > absX && absY > absZ) {
|
|
return y < 0 ? DOWN : UP;
|
|
}
|
|
return orElse;
|
|
}
|
|
|
|
@Contract(value="_,!null->!null;_,_->_")
|
|
public static @Nullable Direction getNearest(Vec3i vec, @Nullable Direction orElse) {
|
|
return Direction.getNearest(vec.getX(), vec.getY(), vec.getZ(), orElse);
|
|
}
|
|
|
|
public String toString() {
|
|
return this.name;
|
|
}
|
|
|
|
@Override
|
|
public String getSerializedName() {
|
|
return this.name;
|
|
}
|
|
|
|
private static DataResult<Direction> verifyVertical(Direction v) {
|
|
return v.getAxis().isVertical() ? DataResult.success((Object)v) : DataResult.error(() -> "Expected a vertical direction");
|
|
}
|
|
|
|
public static Direction get(AxisDirection axisDirection, Axis axis) {
|
|
for (Direction direction : VALUES) {
|
|
if (direction.getAxisDirection() != axisDirection || direction.getAxis() != axis) continue;
|
|
return direction;
|
|
}
|
|
throw new IllegalArgumentException("No such direction: " + String.valueOf((Object)axisDirection) + " " + String.valueOf(axis));
|
|
}
|
|
|
|
public static ImmutableList<Axis> axisStepOrder(Vec3 movement) {
|
|
if (Math.abs(movement.x) < Math.abs(movement.z)) {
|
|
return YZX_AXIS_ORDER;
|
|
}
|
|
return YXZ_AXIS_ORDER;
|
|
}
|
|
|
|
public Vec3i getUnitVec3i() {
|
|
return this.normal;
|
|
}
|
|
|
|
public Vec3 getUnitVec3() {
|
|
return this.normalVec3;
|
|
}
|
|
|
|
public Vector3fc getUnitVec3f() {
|
|
return this.normalVec3f;
|
|
}
|
|
|
|
public boolean isFacingAngle(float yAngle) {
|
|
float radians = yAngle * ((float)Math.PI / 180);
|
|
float dx = -Mth.sin(radians);
|
|
float dz = Mth.cos(radians);
|
|
return (float)this.normal.getX() * dx + (float)this.normal.getZ() * dz > 0.0f;
|
|
}
|
|
|
|
static {
|
|
CODEC = StringRepresentable.fromEnum(Direction::values);
|
|
VERTICAL_CODEC = CODEC.validate(Direction::verifyVertical);
|
|
BY_ID = ByIdMap.continuous(Direction::get3DDataValue, Direction.values(), ByIdMap.OutOfBoundsStrategy.WRAP);
|
|
STREAM_CODEC = ByteBufCodecs.idMapper(BY_ID, Direction::get3DDataValue);
|
|
LEGACY_ID_CODEC = Codec.BYTE.xmap(Direction::from3DDataValue, d -> (byte)d.get3DDataValue());
|
|
LEGACY_ID_CODEC_2D = Codec.BYTE.xmap(Direction::from2DDataValue, d -> (byte)d.get2DDataValue());
|
|
YXZ_AXIS_ORDER = ImmutableList.of((Object)Axis.Y, (Object)Axis.X, (Object)Axis.Z);
|
|
YZX_AXIS_ORDER = ImmutableList.of((Object)Axis.Y, (Object)Axis.Z, (Object)Axis.X);
|
|
VALUES = Direction.values();
|
|
BY_3D_DATA = (Direction[])Arrays.stream(VALUES).sorted(Comparator.comparingInt(d -> d.data3d)).toArray(Direction[]::new);
|
|
BY_2D_DATA = (Direction[])Arrays.stream(VALUES).filter(d -> d.getAxis().isHorizontal()).sorted(Comparator.comparingInt(d -> d.data2d)).toArray(Direction[]::new);
|
|
}
|
|
|
|
public static enum Axis implements Predicate<Direction>,
|
|
StringRepresentable
|
|
{
|
|
X("x"){
|
|
|
|
@Override
|
|
public int choose(int x, int y, int z) {
|
|
return x;
|
|
}
|
|
|
|
@Override
|
|
public boolean choose(boolean x, boolean y, boolean z) {
|
|
return x;
|
|
}
|
|
|
|
@Override
|
|
public double choose(double x, double y, double z) {
|
|
return x;
|
|
}
|
|
|
|
@Override
|
|
public Direction getPositive() {
|
|
return EAST;
|
|
}
|
|
|
|
@Override
|
|
public Direction getNegative() {
|
|
return WEST;
|
|
}
|
|
}
|
|
,
|
|
Y("y"){
|
|
|
|
@Override
|
|
public int choose(int x, int y, int z) {
|
|
return y;
|
|
}
|
|
|
|
@Override
|
|
public double choose(double x, double y, double z) {
|
|
return y;
|
|
}
|
|
|
|
@Override
|
|
public boolean choose(boolean x, boolean y, boolean z) {
|
|
return y;
|
|
}
|
|
|
|
@Override
|
|
public Direction getPositive() {
|
|
return UP;
|
|
}
|
|
|
|
@Override
|
|
public Direction getNegative() {
|
|
return DOWN;
|
|
}
|
|
}
|
|
,
|
|
Z("z"){
|
|
|
|
@Override
|
|
public int choose(int x, int y, int z) {
|
|
return z;
|
|
}
|
|
|
|
@Override
|
|
public double choose(double x, double y, double z) {
|
|
return z;
|
|
}
|
|
|
|
@Override
|
|
public boolean choose(boolean x, boolean y, boolean z) {
|
|
return z;
|
|
}
|
|
|
|
@Override
|
|
public Direction getPositive() {
|
|
return SOUTH;
|
|
}
|
|
|
|
@Override
|
|
public Direction getNegative() {
|
|
return NORTH;
|
|
}
|
|
};
|
|
|
|
public static final Axis[] VALUES;
|
|
public static final StringRepresentable.EnumCodec<Axis> CODEC;
|
|
private final String name;
|
|
|
|
private Axis(String name) {
|
|
this.name = name;
|
|
}
|
|
|
|
public static @Nullable Axis byName(String name) {
|
|
return CODEC.byName(name);
|
|
}
|
|
|
|
public String getName() {
|
|
return this.name;
|
|
}
|
|
|
|
public boolean isVertical() {
|
|
return this == Y;
|
|
}
|
|
|
|
public boolean isHorizontal() {
|
|
return this == X || this == Z;
|
|
}
|
|
|
|
public abstract Direction getPositive();
|
|
|
|
public abstract Direction getNegative();
|
|
|
|
public Direction[] getDirections() {
|
|
return new Direction[]{this.getPositive(), this.getNegative()};
|
|
}
|
|
|
|
public String toString() {
|
|
return this.name;
|
|
}
|
|
|
|
public static Axis getRandom(RandomSource random) {
|
|
return Util.getRandom(VALUES, random);
|
|
}
|
|
|
|
@Override
|
|
public boolean test(@Nullable Direction input) {
|
|
return input != null && input.getAxis() == this;
|
|
}
|
|
|
|
public Plane getPlane() {
|
|
return switch (this.ordinal()) {
|
|
default -> throw new MatchException(null, null);
|
|
case 0, 2 -> Plane.HORIZONTAL;
|
|
case 1 -> Plane.VERTICAL;
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public String getSerializedName() {
|
|
return this.name;
|
|
}
|
|
|
|
public abstract int choose(int var1, int var2, int var3);
|
|
|
|
public abstract double choose(double var1, double var3, double var5);
|
|
|
|
public abstract boolean choose(boolean var1, boolean var2, boolean var3);
|
|
|
|
static {
|
|
VALUES = Axis.values();
|
|
CODEC = StringRepresentable.fromEnum(Axis::values);
|
|
}
|
|
}
|
|
|
|
public static enum AxisDirection {
|
|
POSITIVE(1, "Towards positive"),
|
|
NEGATIVE(-1, "Towards negative");
|
|
|
|
private final int step;
|
|
private final String name;
|
|
|
|
private AxisDirection(int step, String name) {
|
|
this.step = step;
|
|
this.name = name;
|
|
}
|
|
|
|
public int getStep() {
|
|
return this.step;
|
|
}
|
|
|
|
public String getName() {
|
|
return this.name;
|
|
}
|
|
|
|
public String toString() {
|
|
return this.name;
|
|
}
|
|
|
|
public AxisDirection opposite() {
|
|
return this == POSITIVE ? NEGATIVE : POSITIVE;
|
|
}
|
|
}
|
|
|
|
public static enum Plane implements Predicate<Direction>,
|
|
Iterable<Direction>
|
|
{
|
|
HORIZONTAL(new Direction[]{NORTH, EAST, SOUTH, WEST}, new Axis[]{Axis.X, Axis.Z}),
|
|
VERTICAL(new Direction[]{UP, DOWN}, new Axis[]{Axis.Y});
|
|
|
|
private final Direction[] faces;
|
|
private final Axis[] axis;
|
|
|
|
private Plane(Direction[] faces, Axis[] axis) {
|
|
this.faces = faces;
|
|
this.axis = axis;
|
|
}
|
|
|
|
public Direction getRandomDirection(RandomSource random) {
|
|
return Util.getRandom(this.faces, random);
|
|
}
|
|
|
|
public Axis getRandomAxis(RandomSource random) {
|
|
return Util.getRandom(this.axis, random);
|
|
}
|
|
|
|
@Override
|
|
public boolean test(@Nullable Direction input) {
|
|
return input != null && input.getAxis().getPlane() == this;
|
|
}
|
|
|
|
@Override
|
|
public Iterator<Direction> iterator() {
|
|
return Iterators.forArray((Object[])this.faces);
|
|
}
|
|
|
|
public Stream<Direction> stream() {
|
|
return Arrays.stream(this.faces);
|
|
}
|
|
|
|
public List<Direction> shuffledCopy(RandomSource random) {
|
|
return Util.shuffledCopy(this.faces, random);
|
|
}
|
|
|
|
public int length() {
|
|
return this.faces.length;
|
|
}
|
|
}
|
|
}
|
|
|