mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-08 01:17:47 +01:00
Implement local coordinate parsing
This commit is contained in:
parent
1ac99fa44c
commit
e1d1f52c3d
@ -7,6 +7,7 @@ import net.minestom.server.utils.StringUtils;
|
|||||||
import net.minestom.server.utils.location.RelativeVec;
|
import net.minestom.server.utils.location.RelativeVec;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,10 +15,13 @@ import java.util.function.Function;
|
|||||||
*/
|
*/
|
||||||
abstract class ArgumentRelativeVec extends Argument<RelativeVec> {
|
abstract class ArgumentRelativeVec extends Argument<RelativeVec> {
|
||||||
|
|
||||||
public static final String RELATIVE_CHAR = "~";
|
public static final char RELATIVE_CHAR = '~';
|
||||||
|
public static final char LOCAL_CHAR = '^';
|
||||||
|
public static final Set<Character> MODIFIER_CHARS = Set.of(RELATIVE_CHAR, LOCAL_CHAR);
|
||||||
|
|
||||||
public static final int INVALID_NUMBER_COUNT_ERROR = 1;
|
public static final int INVALID_NUMBER_COUNT_ERROR = 1;
|
||||||
public static final int INVALID_NUMBER_ERROR = 2;
|
public static final int INVALID_NUMBER_ERROR = 2;
|
||||||
|
public static final int MIXED_TYPE_ERROR = 3;
|
||||||
|
|
||||||
private final int numberCount;
|
private final int numberCount;
|
||||||
|
|
||||||
@ -39,13 +43,21 @@ abstract class ArgumentRelativeVec extends Argument<RelativeVec> {
|
|||||||
|
|
||||||
double[] coordinates = new double[split.length];
|
double[] coordinates = new double[split.length];
|
||||||
boolean[] isRelative = new boolean[split.length];
|
boolean[] isRelative = new boolean[split.length];
|
||||||
|
Type type = Type.UNDEFINED;
|
||||||
for (int i = 0; i < split.length; i++) {
|
for (int i = 0; i < split.length; i++) {
|
||||||
final String element = split[i];
|
final String element = split[i];
|
||||||
try {
|
try {
|
||||||
if (element.startsWith(RELATIVE_CHAR)) {
|
final char modifierChar = element.charAt(0);
|
||||||
|
if (MODIFIER_CHARS.contains(modifierChar)) {
|
||||||
isRelative[i] = true;
|
isRelative[i] = true;
|
||||||
|
|
||||||
if (element.length() != RELATIVE_CHAR.length()) {
|
if (type == Type.UNDEFINED) {
|
||||||
|
type = modifierChar == LOCAL_CHAR ? Type.LOCAL : Type.RELATIVE;
|
||||||
|
} else if (type != (modifierChar == LOCAL_CHAR ? Type.LOCAL : Type.RELATIVE)) {
|
||||||
|
throw new ArgumentSyntaxException("Cannot mix world & local coordinates (everything must either use ^ or not)", input, MIXED_TYPE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.length() > 1) {
|
||||||
final String potentialNumber = element.substring(1);
|
final String potentialNumber = element.substring(1);
|
||||||
coordinates[i] = getRelativeNumberParser().apply(potentialNumber).doubleValue();
|
coordinates[i] = getRelativeNumberParser().apply(potentialNumber).doubleValue();
|
||||||
}
|
}
|
||||||
@ -53,12 +65,12 @@ abstract class ArgumentRelativeVec extends Argument<RelativeVec> {
|
|||||||
coordinates[i] = getAbsoluteNumberParser().apply(element).doubleValue();
|
coordinates[i] = getAbsoluteNumberParser().apply(element).doubleValue();
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new ArgumentSyntaxException("Invalid number", String.join(StringUtils.SPACE, split), INVALID_NUMBER_ERROR);
|
throw new ArgumentSyntaxException("Invalid number", input, INVALID_NUMBER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RelativeVec(split.length == 3 ? new Vec(coordinates[0], coordinates[1], coordinates[2]) : new Vec(coordinates[0], coordinates[1]),
|
return new RelativeVec(split.length == 3 ? new Vec(coordinates[0], coordinates[1], coordinates[2]) : new Vec(coordinates[0], coordinates[1]),
|
||||||
isRelative[0], split.length == 3 && isRelative[1], isRelative[split.length == 3 ? 2 : 1]);
|
isRelative, type == Type.LOCAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,4 +81,10 @@ abstract class ArgumentRelativeVec extends Argument<RelativeVec> {
|
|||||||
public int getNumberCount() {
|
public int getNumberCount() {
|
||||||
return numberCount;
|
return numberCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum Type {
|
||||||
|
RELATIVE,
|
||||||
|
LOCAL,
|
||||||
|
UNDEFINED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,9 @@ import java.util.Objects;
|
|||||||
public final class RelativeVec {
|
public final class RelativeVec {
|
||||||
|
|
||||||
private final Vec vec;
|
private final Vec vec;
|
||||||
private final boolean relativeX, relativeY, relativeZ;
|
private boolean relativeX, relativeY, relativeZ;
|
||||||
|
private boolean[] relative;
|
||||||
|
private boolean isLocal;
|
||||||
|
|
||||||
public RelativeVec(@NotNull Vec vec, boolean relativeX, boolean relativeY, boolean relativeZ) {
|
public RelativeVec(@NotNull Vec vec, boolean relativeX, boolean relativeY, boolean relativeZ) {
|
||||||
this.vec = vec;
|
this.vec = vec;
|
||||||
@ -27,6 +29,12 @@ public final class RelativeVec {
|
|||||||
this.relativeZ = relativeZ;
|
this.relativeZ = relativeZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RelativeVec(Vec vec, boolean[] relative, boolean isLocal) {
|
||||||
|
this.vec = vec;
|
||||||
|
this.relative = relative;
|
||||||
|
this.isLocal = isLocal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the location based on the relative fields and {@code position}.
|
* Gets the location based on the relative fields and {@code position}.
|
||||||
*
|
*
|
||||||
@ -62,8 +70,9 @@ public final class RelativeVec {
|
|||||||
* @return the location
|
* @return the location
|
||||||
*/
|
*/
|
||||||
public @NotNull Vec from(@Nullable Entity entity) {
|
public @NotNull Vec from(@Nullable Entity entity) {
|
||||||
final var entityPosition = entity != null ? entity.getPosition() : Pos.ZERO;
|
return isLocal ? toGlobal(vec, entity.getPosition(), relative) : toGlobal(vec, entity.getPosition().asVec(), relative);
|
||||||
return from(entityPosition);
|
// final var entityPosition = entity != null ? entity.getPosition() : Pos.ZERO;
|
||||||
|
// return from(entityPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull Vec fromSender(@Nullable CommandSender sender) {
|
public @NotNull Vec fromSender(@Nullable CommandSender sender) {
|
||||||
@ -104,4 +113,30 @@ public final class RelativeVec {
|
|||||||
return relativeZ;
|
return relativeZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vec toGlobal(Vec local, Pos origin, boolean[] axis) {
|
||||||
|
double double5 = Math.cos(Math.toRadians(origin.yaw() + 90.0f));
|
||||||
|
double double6 = Math.sin(Math.toRadians(origin.yaw() + 90.0f));
|
||||||
|
double double7 = Math.cos(Math.toRadians(-origin.pitch()));
|
||||||
|
double double8 = Math.sin(Math.toRadians(-origin.pitch()));
|
||||||
|
double double9 = Math.cos(Math.toRadians(-origin.pitch() + 90.0f));
|
||||||
|
double double10 = Math.sin(Math.toRadians(-origin.pitch() + 90.0f));
|
||||||
|
Vec dna11 = new Vec(double5 * double7, double8, double6 * double7);
|
||||||
|
Vec dna12 = new Vec(double5 * double9, double10, double6 * double9);
|
||||||
|
Vec dna13 = dna11.cross(dna12).mul(-1);
|
||||||
|
double double14 = dna11.x() * local.z() + dna12.x() * local.y() + dna13.x() * local.x();
|
||||||
|
double double16 = dna11.y() * local.z() + dna12.y() * local.y() + dna13.y() * local.x();
|
||||||
|
double double18 = dna11.z() * local.z() + dna12.z() * local.y() + dna13.z() * local.x();
|
||||||
|
return new Vec(double14 + (axis[0] ? origin.x() : 0), double16 + (axis[1] ? origin.y() : 0), double18 + (axis[2] ? origin.z() : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec toGlobal(Vec relative, Vec origin, boolean[] axis) {
|
||||||
|
if (!axis[0] && !axis[1] && !axis[2]) {
|
||||||
|
return relative;
|
||||||
|
}
|
||||||
|
final var absolute = Objects.requireNonNullElse(origin, Vec.ZERO);
|
||||||
|
final double x = relative.x() + (axis[0] ? absolute.x() : 0);
|
||||||
|
final double y = relative.y() + (axis[1] ? absolute.y() : 0);
|
||||||
|
final double z = relative.z() + (axis[2] ? absolute.z() : 0);
|
||||||
|
return new Vec(x, y, z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,8 @@ public class TeleportCommand extends Command {
|
|||||||
final Player player = sender.asPlayer();
|
final Player player = sender.asPlayer();
|
||||||
|
|
||||||
final RelativeVec relativeVec = context.get("pos");
|
final RelativeVec relativeVec = context.get("pos");
|
||||||
final Vec position = relativeVec.from(player);
|
final Pos position = player.getPosition().withCoord(relativeVec.from(player));
|
||||||
player.teleport(new Pos(position));
|
player.teleport(position);
|
||||||
player.sendMessage(Component.text("You have been teleported to " + position));
|
player.sendMessage(Component.text("You have been teleported to " + position));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user