minecraft-src/net/minecraft/core/Vec3i.java
2025-07-04 02:49:36 +03:00

264 lines
6.5 KiB
Java

package net.minecraft.core;
import com.google.common.base.MoreObjects;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import java.util.stream.IntStream;
import net.minecraft.Util;
import net.minecraft.util.Mth;
import org.jetbrains.annotations.Unmodifiable;
@Unmodifiable
public class Vec3i implements Comparable<Vec3i> {
public static final Codec<Vec3i> CODEC = Codec.INT_STREAM
.comapFlatMap(
intStream -> Util.fixedSize(intStream, 3).map(is -> new Vec3i(is[0], is[1], is[2])),
vec3i -> IntStream.of(new int[]{vec3i.getX(), vec3i.getY(), vec3i.getZ()})
);
/**
* An immutable vector with zero as all coordinates.
*/
public static final Vec3i ZERO = new Vec3i(0, 0, 0);
private int x;
private int y;
private int z;
public static Codec<Vec3i> offsetCodec(int maxOffset) {
return CODEC.validate(
vec3i -> Math.abs(vec3i.getX()) < maxOffset && Math.abs(vec3i.getY()) < maxOffset && Math.abs(vec3i.getZ()) < maxOffset
? DataResult.success(vec3i)
: DataResult.error(() -> "Position out of range, expected at most " + maxOffset + ": " + vec3i)
);
}
public Vec3i(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (!(object instanceof Vec3i vec3i)) {
return false;
} else if (this.getX() != vec3i.getX()) {
return false;
} else {
return this.getY() != vec3i.getY() ? false : this.getZ() == vec3i.getZ();
}
}
public int hashCode() {
return (this.getY() + this.getZ() * 31) * 31 + this.getX();
}
public int compareTo(Vec3i other) {
if (this.getY() == other.getY()) {
return this.getZ() == other.getZ() ? this.getX() - other.getX() : this.getZ() - other.getZ();
} else {
return this.getY() - other.getY();
}
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getZ() {
return this.z;
}
protected Vec3i setX(int x) {
this.x = x;
return this;
}
protected Vec3i setY(int y) {
this.y = y;
return this;
}
protected Vec3i setZ(int z) {
this.z = z;
return this;
}
public Vec3i offset(int dx, int dy, int dz) {
return dx == 0 && dy == 0 && dz == 0 ? this : new Vec3i(this.getX() + dx, this.getY() + dy, this.getZ() + dz);
}
public Vec3i offset(Vec3i vector) {
return this.offset(vector.getX(), vector.getY(), vector.getZ());
}
public Vec3i subtract(Vec3i vector) {
return this.offset(-vector.getX(), -vector.getY(), -vector.getZ());
}
public Vec3i multiply(int scalar) {
if (scalar == 1) {
return this;
} else {
return scalar == 0 ? ZERO : new Vec3i(this.getX() * scalar, this.getY() * scalar, this.getZ() * scalar);
}
}
/**
* Offset this vector 1 unit up
*/
public Vec3i above() {
return this.above(1);
}
/**
* Offset this vector upwards by the given distance.
*/
public Vec3i above(int distance) {
return this.relative(Direction.UP, distance);
}
/**
* Offset this vector 1 unit down
*/
public Vec3i below() {
return this.below(1);
}
/**
* Offset this vector downwards by the given distance.
*/
public Vec3i below(int distance) {
return this.relative(Direction.DOWN, distance);
}
public Vec3i north() {
return this.north(1);
}
public Vec3i north(int distance) {
return this.relative(Direction.NORTH, distance);
}
public Vec3i south() {
return this.south(1);
}
public Vec3i south(int distance) {
return this.relative(Direction.SOUTH, distance);
}
public Vec3i west() {
return this.west(1);
}
public Vec3i west(int distance) {
return this.relative(Direction.WEST, distance);
}
public Vec3i east() {
return this.east(1);
}
public Vec3i east(int distance) {
return this.relative(Direction.EAST, distance);
}
public Vec3i relative(Direction direction) {
return this.relative(direction, 1);
}
/**
* Offsets this Vector by the given distance in the specified direction.
*/
public Vec3i relative(Direction direction, int distance) {
return distance == 0
? this
: new Vec3i(this.getX() + direction.getStepX() * distance, this.getY() + direction.getStepY() * distance, this.getZ() + direction.getStepZ() * distance);
}
public Vec3i relative(Direction.Axis axis, int amount) {
if (amount == 0) {
return this;
} else {
int i = axis == Direction.Axis.X ? amount : 0;
int j = axis == Direction.Axis.Y ? amount : 0;
int k = axis == Direction.Axis.Z ? amount : 0;
return new Vec3i(this.getX() + i, this.getY() + j, this.getZ() + k);
}
}
/**
* Calculate the cross product of this and the given Vector
*/
public Vec3i cross(Vec3i vector) {
return new Vec3i(
this.getY() * vector.getZ() - this.getZ() * vector.getY(),
this.getZ() * vector.getX() - this.getX() * vector.getZ(),
this.getX() * vector.getY() - this.getY() * vector.getX()
);
}
public boolean closerThan(Vec3i vector, double distance) {
return this.distSqr(vector) < Mth.square(distance);
}
public boolean closerToCenterThan(Position position, double distance) {
return this.distToCenterSqr(position) < Mth.square(distance);
}
/**
* Calculate squared distance to the given Vector
*/
public double distSqr(Vec3i vector) {
return this.distToLowCornerSqr(vector.getX(), vector.getY(), vector.getZ());
}
public double distToCenterSqr(Position position) {
return this.distToCenterSqr(position.x(), position.y(), position.z());
}
public double distToCenterSqr(double x, double y, double z) {
double d = this.getX() + 0.5 - x;
double e = this.getY() + 0.5 - y;
double f = this.getZ() + 0.5 - z;
return d * d + e * e + f * f;
}
public double distToLowCornerSqr(double x, double y, double z) {
double d = this.getX() - x;
double e = this.getY() - y;
double f = this.getZ() - z;
return d * d + e * e + f * f;
}
public int distManhattan(Vec3i vector) {
float f = Math.abs(vector.getX() - this.getX());
float g = Math.abs(vector.getY() - this.getY());
float h = Math.abs(vector.getZ() - this.getZ());
return (int)(f + g + h);
}
public int distChessboard(Vec3i vector) {
int i = Math.abs(this.getX() - vector.getX());
int j = Math.abs(this.getY() - vector.getY());
int k = Math.abs(this.getZ() - vector.getZ());
return Math.max(Math.max(i, j), k);
}
public int get(Direction.Axis axis) {
return axis.choose(this.x, this.y, this.z);
}
public String toString() {
return MoreObjects.toStringHelper(this).add("x", this.getX()).add("y", this.getY()).add("z", this.getZ()).toString();
}
public String toShortString() {
return this.getX() + ", " + this.getY() + ", " + this.getZ();
}
}