Merge pull request #355 from Minestom/block-position

Coordinate API implementation
This commit is contained in:
TheMode 2021-07-09 00:29:04 +02:00 committed by GitHub
commit e052a28881
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
120 changed files with 1224 additions and 1518 deletions

View File

@ -2,6 +2,7 @@ package net.minestom.demo.largeframebuffers;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.GameMode;
@ -19,7 +20,6 @@ import net.minestom.server.map.framebuffers.LargeGLFWFramebuffer;
import net.minestom.server.map.framebuffers.LargeGraphics2DFramebuffer;
import net.minestom.server.map.framebuffers.MapColorRenderer;
import net.minestom.server.network.packet.server.play.MapDataPacket;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.time.TimeUnit;
import java.awt.*;
@ -86,8 +86,7 @@ public class Demo {
itemFrameMeta.setNotifyAboutChanges(true);
itemFrame.setInstance(instance, new Position(x, y, z));
itemFrame.getPosition().setYaw(180f);
itemFrame.setInstance(instance, new Pos(x, y, z, 180, 0));
}
private static void setupMaps(Instance instance, int mapIDStart, int zCoordinate) {

View File

@ -1,6 +1,7 @@
package net.minestom.demo.largeframebuffers;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.event.player.PlayerLoginEvent;
import net.minestom.server.event.player.PlayerSpawnEvent;
@ -8,7 +9,6 @@ import net.minestom.server.instance.*;
import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.ConnectionManager;
import net.minestom.server.utils.Position;
import net.minestom.server.world.biomes.Biome;
import org.jetbrains.annotations.NotNull;
@ -35,12 +35,12 @@ public class MainDemo {
// Set the spawning instance
player.addEventCallback(PlayerLoginEvent.class, event -> {
event.setSpawningInstance(instanceContainer);
player.setRespawnPoint(new Position(0, 45, 0));
player.setRespawnPoint(new Pos(0, 45, 0));
});
// Teleport the player at spawn
player.addEventCallback(PlayerSpawnEvent.class, event -> {
player.teleport(new Position(0, 45, 0));
player.teleport(new Pos(0, 45, 0));
player.setGameMode(GameMode.CREATIVE);
});
});

View File

@ -15,7 +15,6 @@ import net.minestom.server.network.packet.server.play.SoundEffectPacket;
import net.minestom.server.network.packet.server.play.StopSoundPacket;
import net.minestom.server.registry.Registries;
import net.minestom.server.sound.SoundEvent;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@ -25,6 +24,7 @@ import java.util.Collection;
*/
public class AdventurePacketConvertor {
private static final Object2IntMap<NamedTextColor> NAMED_TEXT_COLOR_ID_MAP = new Object2IntArrayMap<>(16);
static {
NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.BLACK, 0);
NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.DARK_BLUE, 1);
@ -102,9 +102,9 @@ public class AdventurePacketConvertor {
* Creates a sound packet from a sound and a location.
*
* @param sound the sound
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
* @return the sound packet
*/
public static @NotNull ServerPacket createSoundPacket(@NotNull Sound sound, double x, double y, double z) {
@ -136,7 +136,7 @@ public class AdventurePacketConvertor {
/**
* Creates a sound effect packet from a sound and an emitter.
*
* @param sound the sound
* @param sound the sound
* @param emitter the emitter, must be an {@link Entity}
* @return the sound packet
*/
@ -158,14 +158,13 @@ public class AdventurePacketConvertor {
packet.pitch = sound.pitch();
return packet;
} else {
final Position pos = entity.getPosition();
final var pos = entity.getPosition();
final NamedSoundEffectPacket packet = new NamedSoundEffectPacket();
packet.soundName = sound.name().asString();
packet.soundSource = sound.source();
packet.x = (int) pos.getX();
packet.y = (int) pos.getY();
packet.z = (int) pos.getX();
packet.x = (int) pos.x();
packet.y = (int) pos.y();
packet.z = (int) pos.z();
packet.volume = sound.volume();
packet.pitch = sound.pitch();
return packet;
@ -175,7 +174,7 @@ public class AdventurePacketConvertor {
/**
* Creates an entity sound packet from an Adventure sound.
*
* @param sound the sound
* @param sound the sound
* @param entity the entity the sound is coming from
* @return the packet
* @deprecated Use {@link #createSoundPacket(Sound, Sound.Emitter)}

View File

@ -1,9 +1,8 @@
package net.minestom.server.collision;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.coordinate.Point;
import org.jetbrains.annotations.NotNull;
/**
@ -52,7 +51,7 @@ public class BoundingBox {
}
/**
* Used to know if the bounding box intersects at a {@link BlockPosition}.
* Used to know if the bounding box intersects at a point.
*
* @param blockPosition the position to check
* @return true if the bounding box intersects with the position, false otherwise
@ -150,7 +149,7 @@ public class BoundingBox {
* @return the min X
*/
public double getMinX() {
return entity.getPosition().getX() - (x / 2);
return entity.getPosition().x() - (x / 2);
}
/**
@ -159,7 +158,7 @@ public class BoundingBox {
* @return the max X
*/
public double getMaxX() {
return entity.getPosition().getX() + (x / 2);
return entity.getPosition().x() + (x / 2);
}
/**
@ -168,7 +167,7 @@ public class BoundingBox {
* @return the min Y
*/
public double getMinY() {
return entity.getPosition().getY();
return entity.getPosition().y();
}
/**
@ -177,7 +176,7 @@ public class BoundingBox {
* @return the max Y
*/
public double getMaxY() {
return entity.getPosition().getY() + y;
return entity.getPosition().y() + y;
}
/**
@ -186,7 +185,7 @@ public class BoundingBox {
* @return the min Z
*/
public double getMinZ() {
return entity.getPosition().getZ() - (z / 2);
return entity.getPosition().z() - (z / 2);
}
/**
@ -195,96 +194,96 @@ public class BoundingBox {
* @return the max Z
*/
public double getMaxZ() {
return entity.getPosition().getZ() + (z / 2);
return entity.getPosition().z() + (z / 2);
}
/**
* Gets an array of {@link Vector} representing the points at the bottom of the {@link BoundingBox}.
* Gets an array of {@link Vec} representing the points at the bottom of the {@link BoundingBox}.
*
* @return the points at the bottom of the {@link BoundingBox}
*/
@NotNull
public Vector[] getBottomFace() {
return new Vector[]{
new Vector(getMinX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMinY(), getMaxZ()),
new Vector(getMinX(), getMinY(), getMaxZ()),
public Vec[] getBottomFace() {
return new Vec[]{
new Vec(getMinX(), getMinY(), getMinZ()),
new Vec(getMaxX(), getMinY(), getMinZ()),
new Vec(getMaxX(), getMinY(), getMaxZ()),
new Vec(getMinX(), getMinY(), getMaxZ()),
};
}
/**
* Gets an array of {@link Vector} representing the points at the top of the {@link BoundingBox}.
* Gets an array of {@link Vec} representing the points at the top of the {@link BoundingBox}.
*
* @return the points at the top of the {@link BoundingBox}
*/
@NotNull
public Vector[] getTopFace() {
return new Vector[]{
new Vector(getMinX(), getMaxY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMaxZ()),
new Vector(getMinX(), getMaxY(), getMaxZ()),
public Vec[] getTopFace() {
return new Vec[]{
new Vec(getMinX(), getMaxY(), getMinZ()),
new Vec(getMaxX(), getMaxY(), getMinZ()),
new Vec(getMaxX(), getMaxY(), getMaxZ()),
new Vec(getMinX(), getMaxY(), getMaxZ()),
};
}
/**
* Gets an array of {@link Vector} representing the points on the left face of the {@link BoundingBox}.
* Gets an array of {@link Vec} representing the points on the left face of the {@link BoundingBox}.
*
* @return the points on the left face of the {@link BoundingBox}
*/
@NotNull
public Vector[] getLeftFace() {
return new Vector[]{
new Vector(getMinX(), getMinY(), getMinZ()),
new Vector(getMinX(), getMaxY(), getMinZ()),
new Vector(getMinX(), getMaxY(), getMaxZ()),
new Vector(getMinX(), getMinY(), getMaxZ()),
public Vec[] getLeftFace() {
return new Vec[]{
new Vec(getMinX(), getMinY(), getMinZ()),
new Vec(getMinX(), getMaxY(), getMinZ()),
new Vec(getMinX(), getMaxY(), getMaxZ()),
new Vec(getMinX(), getMinY(), getMaxZ()),
};
}
/**
* Gets an array of {@link Vector} representing the points on the right face of the {@link BoundingBox}.
* Gets an array of {@link Vec} representing the points on the right face of the {@link BoundingBox}.
*
* @return the points on the right face of the {@link BoundingBox}
*/
@NotNull
public Vector[] getRightFace() {
return new Vector[]{
new Vector(getMaxX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMaxZ()),
new Vector(getMaxX(), getMinY(), getMaxZ()),
public Vec[] getRightFace() {
return new Vec[]{
new Vec(getMaxX(), getMinY(), getMinZ()),
new Vec(getMaxX(), getMaxY(), getMinZ()),
new Vec(getMaxX(), getMaxY(), getMaxZ()),
new Vec(getMaxX(), getMinY(), getMaxZ()),
};
}
/**
* Gets an array of {@link Vector} representing the points at the front of the {@link BoundingBox}.
* Gets an array of {@link Vec} representing the points at the front of the {@link BoundingBox}.
*
* @return the points at the front of the {@link BoundingBox}
*/
@NotNull
public Vector[] getFrontFace() {
return new Vector[]{
new Vector(getMinX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMinZ()),
new Vector(getMinX(), getMaxY(), getMinZ()),
public Vec[] getFrontFace() {
return new Vec[]{
new Vec(getMinX(), getMinY(), getMinZ()),
new Vec(getMaxX(), getMinY(), getMinZ()),
new Vec(getMaxX(), getMaxY(), getMinZ()),
new Vec(getMinX(), getMaxY(), getMinZ()),
};
}
/**
* Gets an array of {@link Vector} representing the points at the back of the {@link BoundingBox}.
* Gets an array of {@link Vec} representing the points at the back of the {@link BoundingBox}.
*
* @return the points at the back of the {@link BoundingBox}
*/
@NotNull
public Vector[] getBackFace() {
return new Vector[]{
new Vector(getMinX(), getMinY(), getMaxZ()),
new Vector(getMaxX(), getMinY(), getMaxZ()),
new Vector(getMaxX(), getMaxY(), getMaxZ()),
new Vector(getMinX(), getMaxY(), getMaxZ()),
public Vec[] getBackFace() {
return new Vec[]{
new Vec(getMinX(), getMinY(), getMaxZ()),
new Vec(getMaxX(), getMinY(), getMaxZ()),
new Vec(getMaxX(), getMaxY(), getMaxZ()),
new Vec(getMinX(), getMaxY(), getMaxZ()),
};
}

View File

@ -5,65 +5,46 @@ import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.WorldBorder;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class CollisionUtils {
private static final Vector Y_AXIS = new Vector(0, 1, 0);
private static final Vector X_AXIS = new Vector(1, 0, 0);
private static final Vector Z_AXIS = new Vector(0, 0, 1);
private static final Vec Y_AXIS = new Vec(0, 1, 0);
private static final Vec X_AXIS = new Vec(1, 0, 0);
private static final Vec Z_AXIS = new Vec(0, 0, 1);
/**
* Moves an entity with physics applied (ie checking against blocks)
*
* @param entity the entity to move
* @param deltaPosition
* @param positionOut the Position object in which the new position will be saved
* @param velocityOut the Vector object in which the new velocity will be saved
* @return whether this entity is on the ground
* @return the result of physics simulation
*/
public static boolean handlePhysics(@NotNull Entity entity,
@NotNull Vector deltaPosition,
@NotNull Position positionOut,
@NotNull Vector velocityOut) {
public static PhysicsResult handlePhysics(@NotNull Entity entity, @NotNull Vec deltaPosition) {
// TODO handle collisions with nearby entities (should it be done here?)
final Instance instance = entity.getInstance();
final Chunk originChunk = entity.getChunk();
final Position currentPosition = entity.getPosition();
final Pos currentPosition = entity.getPosition();
final BoundingBox boundingBox = entity.getBoundingBox();
Vector intermediaryPosition = new Vector();
boolean yCollision = stepAxis(instance, originChunk, currentPosition.toVector(), Y_AXIS, deltaPosition.getY(),
intermediaryPosition,
deltaPosition.getY() > 0 ? boundingBox.getTopFace() : boundingBox.getBottomFace());
final StepResult yCollision = stepAxis(instance, originChunk, currentPosition.asVec(), Y_AXIS, deltaPosition.y(),
deltaPosition.y() > 0 ? boundingBox.getTopFace() : boundingBox.getBottomFace());
boolean xCollision = stepAxis(instance, originChunk, intermediaryPosition, X_AXIS, deltaPosition.getX(),
intermediaryPosition,
deltaPosition.getX() < 0 ? boundingBox.getLeftFace() : boundingBox.getRightFace());
final StepResult xCollision = stepAxis(instance, originChunk, yCollision.newPosition, X_AXIS, deltaPosition.x(),
deltaPosition.x() < 0 ? boundingBox.getLeftFace() : boundingBox.getRightFace());
boolean zCollision = stepAxis(instance, originChunk, intermediaryPosition, Z_AXIS, deltaPosition.getZ(),
intermediaryPosition,
deltaPosition.getZ() > 0 ? boundingBox.getBackFace() : boundingBox.getFrontFace());
final StepResult zCollision = stepAxis(instance, originChunk, xCollision.newPosition, Z_AXIS, deltaPosition.z(),
deltaPosition.z() > 0 ? boundingBox.getBackFace() : boundingBox.getFrontFace());
positionOut.setX(intermediaryPosition.getX());
positionOut.setY(intermediaryPosition.getY());
positionOut.setZ(intermediaryPosition.getZ());
velocityOut.copy(deltaPosition);
if (xCollision) {
velocityOut.setX(0f);
}
if (yCollision) {
velocityOut.setY(0f);
}
if (zCollision) {
velocityOut.setZ(0f);
}
return yCollision && deltaPosition.getY() < 0;
return new PhysicsResult(currentPosition.withCoord(zCollision.newPosition),
deltaPosition.apply(((x, y, z) -> new Vec(
xCollision.foundCollision ? 0 : x,
yCollision.foundCollision ? 0 : y,
zCollision.foundCollision ? 0 : z
))), yCollision.foundCollision && deltaPosition.y() < 0);
}
/**
@ -74,111 +55,77 @@ public class CollisionUtils {
* @param startPosition starting position for stepping, can be intermediary position from last step
* @param axis step direction. Works best if unit vector and aligned to an axis
* @param stepAmount how much to step in the direction (in blocks)
* @param positionOut the vector in which to store the new position
* @param corners the corners to check against
* @return true if a collision has been found
* @return result of the step
*/
private static boolean stepAxis(Instance instance,
Chunk originChunk,
Vector startPosition, Vector axis,
double stepAmount, Vector positionOut,
Vector... corners) {
positionOut.copy(startPosition);
private static StepResult stepAxis(Instance instance, Chunk originChunk, Vec startPosition, Vec axis, double stepAmount, Vec... corners) {
if (corners.length == 0)
return false; // avoid degeneracy in following computations
// perform copies to allow in place modifications
// prevents making a lot of new objects. Well at least it reduces the count
BlockPosition[] cornerPositions = new BlockPosition[corners.length];
Vector[] cornersCopy = new Vector[corners.length];
for (int i = 0; i < corners.length; i++) {
cornersCopy[i] = corners[i].clone();
cornerPositions[i] = new BlockPosition(corners[i]);
}
return new StepResult(startPosition, false); // avoid degeneracy in following computations
final Vec[] originalCorners = corners.clone();
final double sign = Math.signum(stepAmount);
final int blockLength = (int) stepAmount;
final double remainingLength = stepAmount - blockLength;
// used to determine if 'remainingLength' should be used
boolean collisionFound = false;
for (int i = 0; i < Math.abs(blockLength); i++) {
if (!stepOnce(instance, originChunk, axis, sign, cornersCopy, cornerPositions)) {
collisionFound = true;
}
if (collisionFound) {
break;
}
if (collisionFound = stepOnce(instance, originChunk, axis, sign, corners)) break;
}
// add remainingLength
if (!collisionFound) {
Vector direction = new Vector();
direction.copy(axis);
collisionFound = !stepOnce(instance, originChunk, direction, remainingLength, cornersCopy, cornerPositions);
collisionFound = stepOnce(instance, originChunk, axis, remainingLength, corners);
}
// find the corner which moved the least
double smallestDisplacement = Double.POSITIVE_INFINITY;
for (int i = 0; i < corners.length; i++) {
final double displacement = corners[i].distance(cornersCopy[i]);
final double displacement = originalCorners[i].distance(corners[i]);
if (displacement < smallestDisplacement) {
smallestDisplacement = displacement;
}
}
positionOut.copy(startPosition);
positionOut.add(smallestDisplacement * axis.getX() * sign, smallestDisplacement * axis.getY() * sign, smallestDisplacement * axis.getZ() * sign);
return collisionFound;
return new StepResult(startPosition.add(new Vec(smallestDisplacement).mul(axis).mul(sign)), collisionFound);
}
/**
* Steps once (by a length of 1 block) on the given axis.
*
* @param instance instance to get blocks from
* @param axis the axis to move along
* @param amount
* @param cornersCopy the corners of the bounding box to consider (mutable)
* @param cornerPositions the corners, converted to BlockPosition (mutable)
* @return false if this method encountered a collision
* @param instance instance to get blocks from
* @param axis the axis to move along
* @param corners the corners of the bounding box to consider
* @return true if found collision
*/
private static boolean stepOnce(Instance instance,
Chunk originChunk,
Vector axis, double amount, Vector[] cornersCopy, BlockPosition[] cornerPositions) {
private static boolean stepOnce(Instance instance, Chunk originChunk, Vec axis, double amount, Vec[] corners) {
final double sign = Math.signum(amount);
for (int cornerIndex = 0; cornerIndex < cornersCopy.length; cornerIndex++) {
Vector corner = cornersCopy[cornerIndex];
BlockPosition blockPos = cornerPositions[cornerIndex];
corner.add(axis.getX() * amount, axis.getY() * amount, axis.getZ() * amount);
blockPos.setX((int) Math.floor(corner.getX()));
blockPos.setY((int) Math.floor(corner.getY()));
blockPos.setZ((int) Math.floor(corner.getZ()));
for (int cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) {
final Vec originalCorner = corners[cornerIndex];
final Vec newCorner = originalCorner.add(axis.mul(amount));
Chunk chunk = ChunkUtils.retrieve(instance, originChunk, blockPos);
Chunk chunk = ChunkUtils.retrieve(instance, originChunk, newCorner);
if (!ChunkUtils.isLoaded(chunk)) {
// Collision at chunk border
return false;
return true;
}
final Block block = chunk.getBlock(blockPos);
final Block block = chunk.getBlock(newCorner);
// TODO: block collision boxes
// TODO: for the moment, always consider a full block
if (block.isSolid()) {
corner.subtract(axis.getX() * amount, axis.getY() * amount, axis.getZ() * amount);
corners[cornerIndex] = originalCorner.apply(((x, y, z) -> new Vec(
Math.abs(axis.x()) > 10e-16 ? newCorner.blockX() - axis.x() * sign : x,
Math.abs(axis.y()) > 10e-16 ? newCorner.blockY() - axis.y() * sign : y,
Math.abs(axis.z()) > 10e-16 ? newCorner.blockZ() - axis.z() * sign : z
)));
if (Math.abs(axis.getX()) > 10e-16) {
corner.setX(blockPos.getX() - axis.getX() * sign);
}
if (Math.abs(axis.getY()) > 10e-16) {
corner.setY(blockPos.getY() - axis.getY() * sign);
}
if (Math.abs(axis.getZ()) > 10e-16) {
corner.setZ(blockPos.getZ() - axis.getZ() * sign);
}
return false;
return true;
}
corners[cornerIndex] = newCorner;
}
return true;
return false;
}
/**
@ -190,8 +137,8 @@ public class CollisionUtils {
* @return the position with the world border collision applied (can be {@code newPosition} if not changed)
*/
@NotNull
public static Position applyWorldBorder(@NotNull Instance instance,
@NotNull Position currentPosition, @NotNull Position newPosition) {
public static Point applyWorldBorder(@NotNull Instance instance,
@NotNull Point currentPosition, @NotNull Point newPosition) {
final WorldBorder worldBorder = instance.getWorldBorder();
final WorldBorder.CollisionAxis collisionAxis = worldBorder.getCollisionAxis(newPosition);
switch (collisionAxis) {
@ -200,15 +147,48 @@ public class CollisionUtils {
return newPosition;
case BOTH:
// Apply Y velocity/gravity
return new Position(currentPosition.getX(), newPosition.getY(), currentPosition.getZ());
return new Vec(currentPosition.x(), newPosition.y(), currentPosition.z());
case X:
// Apply Y/Z velocity/gravity
return new Position(currentPosition.getX(), newPosition.getY(), newPosition.getZ());
return new Vec(currentPosition.x(), newPosition.y(), newPosition.z());
case Z:
// Apply X/Y velocity/gravity
return new Position(newPosition.getX(), newPosition.getY(), currentPosition.getZ());
return new Vec(newPosition.x(), newPosition.y(), currentPosition.z());
}
throw new IllegalStateException("Something weird happened...");
}
public static class PhysicsResult {
private final Pos newPosition;
private final Vec newVelocity;
private final boolean isOnGround;
public PhysicsResult(Pos newPosition, Vec newVelocity, boolean isOnGround) {
this.newPosition = newPosition;
this.newVelocity = newVelocity;
this.isOnGround = isOnGround;
}
public Pos newPosition() {
return newPosition;
}
public Vec newVelocity() {
return newVelocity;
}
public boolean isOnGround() {
return isOnGround;
}
}
private static class StepResult {
private final Vec newPosition;
private final boolean foundCollision;
public StepResult(Vec newPosition, boolean foundCollision) {
this.newPosition = newPosition;
this.foundCollision = foundCollision;
}
}
}

View File

@ -2,18 +2,18 @@ package net.minestom.server.command.builder.arguments.relative;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.location.RelativeBlockPosition;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.location.RelativeVec;
import org.jetbrains.annotations.NotNull;
/**
* Represents a {@link BlockPosition} with 3 integer numbers (x;y;z) which can take relative coordinates.
* Represents a block position with 3 integers (x;y;z) which can take relative coordinates.
* <p>
* Example: 5 ~ -3
*/
public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBlockPosition> {
public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeVec> {
public ArgumentRelativeBlockPosition(@NotNull String id) {
super(id, 3);
@ -21,19 +21,17 @@ public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBloc
@NotNull
@Override
public RelativeBlockPosition parse(@NotNull String input) throws ArgumentSyntaxException {
public RelativeVec parse(@NotNull String input) throws ArgumentSyntaxException {
final String[] split = input.split(StringUtils.SPACE);
// Check if the value has enough element to be correct
if (split.length != getNumberCount()) {
throw new ArgumentSyntaxException("Invalid number of values", input, INVALID_NUMBER_COUNT_ERROR);
}
BlockPosition blockPosition = new BlockPosition(0, 0, 0);
int x = 0, y = 0, z = 0;
boolean relativeX = false;
boolean relativeY = false;
boolean relativeZ = false;
for (int i = 0; i < split.length; i++) {
final String element = split[i];
if (element.startsWith(RELATIVE_CHAR)) {
@ -51,11 +49,11 @@ public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBloc
final String potentialNumber = element.substring(1);
final int number = Integer.parseInt(potentialNumber);
if (i == 0) {
blockPosition.setX(number);
x = number;
} else if (i == 1) {
blockPosition.setY(number);
y = number;
} else if (i == 2) {
blockPosition.setZ(number);
z = number;
}
} catch (NumberFormatException e) {
throw new ArgumentSyntaxException("Invalid number", input, INVALID_NUMBER_ERROR);
@ -66,11 +64,11 @@ public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBloc
try {
final int number = Integer.parseInt(element);
if (i == 0) {
blockPosition.setX(number);
x = number;
} else if (i == 1) {
blockPosition.setY(number);
y = number;
} else if (i == 2) {
blockPosition.setZ(number);
z = number;
}
} catch (NumberFormatException e) {
throw new ArgumentSyntaxException("Invalid number", input, INVALID_NUMBER_ERROR);
@ -78,7 +76,7 @@ public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBloc
}
}
return new RelativeBlockPosition(blockPosition, relativeX, relativeY, relativeZ);
return new RelativeVec(new Vec(x, y, z), relativeX, relativeY, relativeZ);
}
@Override

View File

@ -2,14 +2,14 @@ package net.minestom.server.command.builder.arguments.relative;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.location.RelativeVec;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.location.RelativeVec;
import org.jetbrains.annotations.NotNull;
/**
* Represents a {@link Vector} with 2 floating numbers (x;z) which can take relative coordinates.
* Represents a {@link Vec} with 2 floating numbers (x;z) which can take relative coordinates.
* <p>
* Example: -1.2 ~
*/
@ -23,13 +23,12 @@ public class ArgumentRelativeVec2 extends ArgumentRelative<RelativeVec> {
@Override
public RelativeVec parse(@NotNull String input) throws ArgumentSyntaxException {
final String[] split = input.split(StringUtils.SPACE);
// Check if the value has enough element to be correct
if (split.length != getNumberCount()) {
throw new ArgumentSyntaxException("Invalid number of values", input, INVALID_NUMBER_COUNT_ERROR);
}
Vector vector = new Vector();
double x = 0, z = 0;
boolean relativeX = false;
boolean relativeZ = false;
@ -47,18 +46,18 @@ public class ArgumentRelativeVec2 extends ArgumentRelative<RelativeVec> {
final String potentialNumber = element.substring(1);
final float number = Float.parseFloat(potentialNumber);
if (i == 0) {
vector.setX(number);
x = number;
} else if (i == 1) {
vector.setZ(number);
z = number;
}
}
} else {
final float number = Float.parseFloat(element);
if (i == 0) {
vector.setX(number);
x = number;
} else if (i == 1) {
vector.setZ(number);
z = number;
}
}
} catch (NumberFormatException e) {
@ -66,7 +65,7 @@ public class ArgumentRelativeVec2 extends ArgumentRelative<RelativeVec> {
}
}
return new RelativeVec(vector, relativeX, false, relativeZ);
return new RelativeVec(new Vec(x, z), relativeX, false, relativeZ);
}
@Override

View File

@ -2,14 +2,14 @@ package net.minestom.server.command.builder.arguments.relative;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.location.RelativeVec;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.location.RelativeVec;
import org.jetbrains.annotations.NotNull;
/**
* Represents a {@link Vector} with 3 floating numbers (x;y;z) which can take relative coordinates.
* Represents a {@link Vec} with 3 floating numbers (x;y;z) which can take relative coordinates.
* <p>
* Example: -1.2 ~ 5
*/
@ -23,17 +23,15 @@ public class ArgumentRelativeVec3 extends ArgumentRelative<RelativeVec> {
@Override
public RelativeVec parse(@NotNull String input) throws ArgumentSyntaxException {
final String[] split = input.split(StringUtils.SPACE);
// Check if the value has enough element to be correct
if (split.length != getNumberCount()) {
throw new ArgumentSyntaxException("Invalid number of values", input, INVALID_NUMBER_COUNT_ERROR);
}
Vector vector = new Vector();
double x = 0, y = 0, z = 0;
boolean relativeX = false;
boolean relativeY = false;
boolean relativeZ = false;
for (int i = 0; i < split.length; i++) {
final String element = split[i];
try {
@ -50,22 +48,22 @@ public class ArgumentRelativeVec3 extends ArgumentRelative<RelativeVec> {
final String potentialNumber = element.substring(1);
final float number = Float.parseFloat(potentialNumber);
if (i == 0) {
vector.setX(number);
x = number;
} else if (i == 1) {
vector.setY(number);
y = number;
} else if (i == 2) {
vector.setZ(number);
z = number;
}
}
} else {
final float number = Float.parseFloat(element);
if (i == 0) {
vector.setX(number);
x = number;
} else if (i == 1) {
vector.setY(number);
y = number;
} else if (i == 2) {
vector.setZ(number);
z = number;
}
}
} catch (NumberFormatException e) {
@ -73,7 +71,7 @@ public class ArgumentRelativeVec3 extends ArgumentRelative<RelativeVec> {
}
}
return new RelativeVec(vector, relativeX, relativeY, relativeZ);
return new RelativeVec(new Vec(x, y, z), relativeX, relativeY, relativeZ);
}
@Override

View File

@ -1,6 +1,8 @@
package net.minestom.server.utils.coordinate;
package net.minestom.server.coordinate;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.chunk.ChunkUtils;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@ -109,6 +111,25 @@ public interface Point {
@Contract(pure = true)
@NotNull Point div(double value);
@Contract(pure = true)
default @NotNull Point relative(@NotNull BlockFace face) {
switch (face) {
case BOTTOM:
return sub(0, 1, 0);
case TOP:
return add(0, 1, 0);
case NORTH:
return sub(0, 0, 1);
case SOUTH:
return add(0, 0, 1);
case WEST:
return sub(1, 0, 0);
case EAST:
return add(1, 0, 0);
}
return this; // should never be called
}
/**
* Gets the distance between this point and another. The value of this
* method is not cached and uses a costly square-root function, so do not
@ -138,4 +159,27 @@ public interface Point {
MathUtils.square(y() - point.y()) +
MathUtils.square(z() - point.z());
}
/**
* Checks it two points have similar (x/y/z).
*
* @param point the point to compare
* @return true if the two positions are similar
*/
default boolean samePoint(@NotNull Point point) {
return Double.compare(point.x(), x()) == 0 &&
Double.compare(point.y(), y()) == 0 &&
Double.compare(point.z(), z()) == 0;
}
/**
* Gets if two points are in the same chunk.
*
* @param point the point to compare two
* @return true if 'this' is in the same chunk as {@code position}
*/
default boolean inSameChunk(@NotNull Point point) {
return ChunkUtils.getChunkCoordinate(x()) == ChunkUtils.getChunkCoordinate(point.x()) &&
ChunkUtils.getChunkCoordinate(z()) == ChunkUtils.getChunkCoordinate(point.z());
}
}

View File

@ -1,8 +1,12 @@
package net.minestom.server.utils.coordinate;
package net.minestom.server.coordinate;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.function.DoubleUnaryOperator;
/**
@ -11,6 +15,8 @@ import java.util.function.DoubleUnaryOperator;
* To become record and primitive.
*/
public final class Pos implements Point {
public static final Pos ZERO = new Pos(0, 0, 0);
private final double x, y, z;
private final float yaw, pitch;
@ -34,6 +40,12 @@ public final class Pos implements Point {
this(point, 0, 0);
}
public static @NotNull Pos fromPoint(@NotNull Point point) {
if (point instanceof Pos)
return (Pos) point;
return new Pos(point.x(), point.y(), point.z());
}
@Contract(pure = true)
public @NotNull Pos withCoord(double x, double y, double z) {
return new Pos(x, y, z, yaw, pitch);
@ -49,6 +61,32 @@ public final class Pos implements Point {
return new Pos(x, y, z, yaw, pitch);
}
/**
* Sets the yaw and pitch to point
* in the direction of the point.
*/
@Contract(pure = true)
public @NotNull Pos withDirection(@NotNull Point point) {
/*
* Sin = Opp / Hyp
* Cos = Adj / Hyp
* Tan = Opp / Adj
*
* x = -Opp
* z = Adj
*/
final double x = point.x();
final double z = point.z();
if (x == 0 && z == 0) {
return withPitch(point.y() > 0 ? -90f : 90f);
}
final double theta = Math.atan2(-x, z);
final double xz = Math.sqrt(MathUtils.square(x) + MathUtils.square(z));
final double _2PI = 2 * Math.PI;
return withView((float) Math.toDegrees((theta + _2PI) % _2PI),
(float) Math.toDegrees(Math.atan(-point.y() / xz)));
}
@Contract(pure = true)
public @NotNull Pos withYaw(float yaw) {
return new Pos(x, y, z, yaw, pitch);
@ -69,6 +107,33 @@ public final class Pos implements Point {
return new Pos(x, y, z, yaw, (float) operator.applyAsDouble(pitch));
}
/**
* Checks if two positions have a similar view (yaw/pitch).
*
* @param position the position to compare
* @return true if the two positions have the same view
*/
public boolean sameView(@NotNull Pos position) {
return Float.compare(position.yaw, yaw) == 0 &&
Float.compare(position.pitch, pitch) == 0;
}
/**
* Gets a unit-vector pointing in the direction that this Location is
* facing.
*
* @return a vector pointing the direction of this location's {@link
* #pitch() pitch} and {@link #yaw() yaw}
*/
public @NotNull Vec direction() {
final float rotX = yaw;
final float rotY = pitch;
final double xz = Math.cos(Math.toRadians(rotY));
return new Vec(-xz * Math.sin(Math.toRadians(rotX)),
-Math.sin(Math.toRadians(rotY)),
xz * Math.cos(Math.toRadians(rotX)));
}
@Override
@Contract(pure = true)
public double x() {
@ -188,6 +253,11 @@ public final class Pos implements Point {
return div(value, value, value);
}
@Override
public @NotNull Pos relative(@NotNull BlockFace face) {
return (Pos) Point.super.relative(face);
}
@Contract(pure = true)
public float yaw() {
return yaw;
@ -203,6 +273,34 @@ public final class Pos implements Point {
return new Vec(x, y, z);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pos pos = (Pos) o;
return Double.compare(pos.x, x) == 0 &&
Double.compare(pos.y, y) == 0 &&
Double.compare(pos.z, z) == 0 &&
Float.compare(pos.yaw, yaw) == 0 &&
Float.compare(pos.pitch, pitch) == 0;
}
@Override
public int hashCode() {
return Objects.hash(x, y, z, yaw, pitch);
}
@Override
public String toString() {
return "Pos{" +
"x=" + x +
", y=" + y +
", z=" + z +
", yaw=" + yaw +
", pitch=" + pitch +
'}';
}
@FunctionalInterface
public interface Operator {
@NotNull Pos apply(double x, double y, double z);

View File

@ -1,12 +1,12 @@
package net.minestom.server.utils.coordinate;
package net.minestom.server.coordinate;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.MathUtils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.function.DoubleUnaryOperator;
import java.util.function.UnaryOperator;
/**
* Represents an immutable 3D vector.
@ -58,7 +58,7 @@ public final class Vec implements Point {
* @return the created point
*/
@Contract(pure = true)
public @NotNull Vec with(@NotNull Operator operator) {
public @NotNull Vec apply(@NotNull Operator operator) {
return operator.apply(x, y, z);
}
@ -158,6 +158,11 @@ public final class Vec implements Point {
return div(value, value, value);
}
@Override
public @NotNull Vec relative(@NotNull BlockFace face) {
return (Vec) Point.super.relative(face);
}
@Contract(pure = true)
public @NotNull Vec neg() {
return new Vec(-x, -y, -z);
@ -188,11 +193,6 @@ public final class Vec implements Point {
return new Vec(Math.max(x, value), Math.max(y, value), Math.max(z, value));
}
@Contract(pure = true)
public Vec apply(@NotNull UnaryOperator<@NotNull Vec> operator) {
return operator.apply(this);
}
@Contract(pure = true)
public @NotNull Pos asPosition() {
return new Pos(x, y, z);
@ -392,6 +392,21 @@ public final class Vec implements Point {
@FunctionalInterface
public interface Operator {
/**
* Checks each axis' value, if it's below {@code 1E-6} then it gets replaced with {@code 0}
*/
Operator EPSILON = (x, y, z) -> new Vec(
Math.abs(x) < 1E-6 ? 0 : x,
Math.abs(y) < 1E-6 ? 0 : y,
Math.abs(z) < 1E-6 ? 0 : z
);
Operator FLOOR = (x, y, z) -> new Vec(
MathUtils.floor(x),
MathUtils.floor(y),
MathUtils.floor(z)
);
@NotNull Vec apply(double x, double y, double z);
}

View File

@ -12,6 +12,9 @@ import net.minestom.server.acquirable.Acquirable;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.collision.BoundingBox;
import net.minestom.server.collision.CollisionUtils;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.metadata.EntityMeta;
@ -37,12 +40,9 @@ import net.minestom.server.potion.TimedPotion;
import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagHandler;
import net.minestom.server.thread.ThreadProvider;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.callback.OptionalCallback;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.utils.entity.EntityUtils;
import net.minestom.server.utils.player.PlayerUtils;
import net.minestom.server.utils.time.Cooldown;
@ -77,16 +77,8 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
protected Instance instance;
protected Chunk currentChunk;
protected final Position position;
/**
* Used to calculate delta movement
*/
protected final Position lastPosition;
/**
* Used to check if any change made to the {@link Entity#position} field since
* the last packets sent
*/
protected final Position lastSyncedPosition;
protected Pos position;
protected Pos lastSyncedPosition;
protected boolean onGround;
private BoundingBox boundingBox;
@ -94,7 +86,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
protected Entity vehicle;
// Velocity
protected Vector velocity = new Vector(); // Movement in block per second
protected Vec velocity = Vec.ZERO; // Movement in block per second
protected boolean hasPhysics = true;
/**
@ -159,9 +151,8 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
this.id = generateId();
this.entityType = entityType;
this.uuid = uuid;
this.position = new Position();
this.lastPosition = new Position();
this.lastSyncedPosition = new Position();
this.position = Pos.ZERO;
this.lastSyncedPosition = Pos.ZERO;
setBoundingBox(entityType.getWidth(), entityType.getHeight(), entityType.getWidth());
@ -181,18 +172,6 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
this(entityType, UUID.randomUUID());
}
@Deprecated
public Entity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) {
this(entityType, uuid);
this.position.set(spawnPosition);
this.lastPosition.set(spawnPosition);
}
@Deprecated
public Entity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
this(entityType, UUID.randomUUID(), spawnPosition);
}
/**
* Schedules a task to be run during the next entity tick.
* It ensures that the task will be executed in the same thread as the entity (depending of the {@link ThreadProvider}).
@ -281,31 +260,26 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* @param callback the optional callback executed, even if auto chunk is not enabled
* @throws IllegalStateException if you try to teleport an entity before settings its instance
*/
public void teleport(@NotNull Position position, @Nullable long[] chunks, @Nullable Runnable callback) {
public void teleport(@NotNull Pos position, @Nullable long[] chunks, @Nullable Runnable callback) {
Check.stateCondition(instance == null, "You need to use Entity#setInstance before teleporting an entity!");
final Position teleportPosition = position.clone(); // Prevent synchronization issue
final ChunkCallback endCallback = (chunk) -> {
refreshPosition(teleportPosition);
refreshPosition(position);
synchronizePosition(true);
OptionalCallback.execute(callback);
};
if (chunks == null || chunks.length == 0) {
instance.loadOptionalChunk(teleportPosition, endCallback);
instance.loadOptionalChunk(position, endCallback);
} else {
ChunkUtils.optionalLoadAll(instance, chunks, null, endCallback);
}
}
public void teleport(@NotNull Position position, @Nullable Runnable callback) {
public void teleport(@NotNull Pos position, @Nullable Runnable callback) {
teleport(position, null, callback);
}
public void teleport(@NotNull Position position) {
public void teleport(@NotNull Pos position) {
teleport(position, null);
}
@ -316,7 +290,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* @param pitch the new pitch
*/
public void setView(float yaw, float pitch) {
refreshView(yaw, pitch);
this.position = position.withView(yaw, pitch);
EntityRotationPacket entityRotationPacket = new EntityRotationPacket();
entityRotationPacket.entityId = getEntityId();
@ -332,16 +306,6 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
sendPacketToViewersAndSelf(entityRotationPacket);
}
/**
* Changes the view of the entity.
* Only the yaw and pitch are used.
*
* @param position the new view
*/
public void setView(@NotNull Position position) {
setView(position.getYaw(), position.getPitch());
}
/**
* When set to true, the entity will automatically get new viewers when they come too close.
* This can be use to have complete control over which player can see it, without having to deal with
@ -396,7 +360,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
{
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
entityHeadLookPacket.entityId = getEntityId();
entityHeadLookPacket.yaw = position.getYaw();
entityHeadLookPacket.yaw = position.yaw();
playerConnection.sendPacket(entityHeadLookPacket);
}
@ -510,9 +474,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
}
}
sendPositionUpdate(false);
final boolean isNettyClient = PlayerUtils.isNettyClient(this);
// Entity tick
{
@ -532,30 +494,34 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
if (applyVelocity) {
final float tps = MinecraftServer.TICK_PER_SECOND;
final double newX = position.getX() + velocity.getX() / tps;
final double newY = position.getY() + velocity.getY() / tps;
final double newZ = position.getZ() + velocity.getZ() / tps;
Position newPosition = new Position(newX, newY, newZ);
Vector newVelocityOut = new Vector();
final Pos newPosition;
final Vec newVelocity;
// Gravity force
final double gravityY = hasNoGravity() ? 0 : gravityAcceleration;
final Vector deltaPos = new Vector(
getVelocity().getX() / tps,
getVelocity().getY() / tps - gravityY,
getVelocity().getZ() / tps
final Vec deltaPos = new Vec(
getVelocity().x() / tps,
getVelocity().y() / tps - gravityY,
getVelocity().z() / tps
);
if (this.hasPhysics) {
this.onGround = CollisionUtils.handlePhysics(this, deltaPos, newPosition, newVelocityOut);
final CollisionUtils.PhysicsResult physicsResult = CollisionUtils.handlePhysics(this, deltaPos);
this.onGround = physicsResult.isOnGround();
newPosition = physicsResult.newPosition();
newVelocity = physicsResult.newVelocity();
} else {
newVelocityOut = deltaPos;
newVelocity = deltaPos;
newPosition = new Pos(
position.x() + velocity.x() / tps,
position.y() + velocity.y() / tps,
position.z() + velocity.z() / tps
);
}
// World border collision
final Position finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition);
final Point finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition);
final Chunk finalChunk = ChunkUtils.retrieve(instance, currentChunk, finalVelocityPosition);
if (!ChunkUtils.isLoaded(finalChunk)) {
// Entity shouldn't be updated when moving in an unloaded chunk
@ -563,35 +529,30 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
}
// Apply the position if changed
if (!finalVelocityPosition.isSimilar(position)) {
refreshPosition(finalVelocityPosition.getX(),
finalVelocityPosition.getY(),
finalVelocityPosition.getZ());
sendPositionUpdate(true);
if (!finalVelocityPosition.samePoint(position)) {
refreshPosition((Pos) finalVelocityPosition, true);
}
// Update velocity
if (hasVelocity() || !newVelocityOut.isZero()) {
this.velocity.copy(newVelocityOut);
this.velocity.multiply(tps);
final Block block = finalChunk.getBlock(position.toBlockPosition());
final double drag = block.registry().friction();
if (onGround) {
if (hasVelocity() || !newVelocity.equals(Vec.ZERO)) {
if (onGround && isNettyClient) {
// Stop player velocity
if (isNettyClient) {
this.velocity.zero();
}
}
velocity = Vec.ZERO;
} else {
final Block block = finalChunk.getBlock(position);
final double drag = block.registry().friction();
this.velocity.setX(velocity.getX() * drag);
this.velocity.setZ(velocity.getZ() * drag);
if (!hasNoGravity())
this.velocity.setY(velocity.getY() * (1 - gravityDragPerTick));
if (velocity.equals(new Vector())) {
this.velocity.zero();
velocity = newVelocity
// Convert from blocks/tick to blocks/sec
.mul(tps)
// Apply drag
.apply((x, y, z) -> new Vec(
x * drag,
!hasNoGravity() ? y * (1 - gravityDragPerTick) : y,
z * drag
))
// Prevent infinitely decreasing velocity
.apply(Vec.Operator.EPSILON);
}
}
@ -686,10 +647,10 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* @param clientSide {@code true} if the client triggered this action
*/
protected void sendPositionUpdate(final boolean clientSide) {
final boolean viewChange = !position.hasSimilarView(lastSyncedPosition);
final double distanceX = Math.abs(position.getX() - lastSyncedPosition.getX());
final double distanceY = Math.abs(position.getY() - lastSyncedPosition.getY());
final double distanceZ = Math.abs(position.getZ() - lastSyncedPosition.getZ());
final boolean viewChange = !position.sameView(lastSyncedPosition);
final double distanceX = Math.abs(position.x() - lastSyncedPosition.x());
final double distanceY = Math.abs(position.y() - lastSyncedPosition.y());
final double distanceZ = Math.abs(position.z() - lastSyncedPosition.z());
final boolean positionChange = (distanceX + distanceY + distanceZ) > 0;
if (distanceX > 8 || distanceY > 8 || distanceZ > 8) {
@ -704,7 +665,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
// Fix head rotation
final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
entityHeadLookPacket.entityId = getEntityId();
entityHeadLookPacket.yaw = position.getYaw();
entityHeadLookPacket.yaw = position.yaw();
sendPacketToViewersAndSelf(entityHeadLookPacket);
} else if (positionChange) {
final EntityPositionPacket entityPositionPacket = EntityPositionPacket
@ -713,13 +674,13 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
} else if (viewChange) {
final EntityRotationPacket entityRotationPacket = new EntityRotationPacket();
entityRotationPacket.entityId = getEntityId();
entityRotationPacket.yaw = position.getYaw();
entityRotationPacket.pitch = position.getPitch();
entityRotationPacket.yaw = position.yaw();
entityRotationPacket.pitch = position.pitch();
entityRotationPacket.onGround = onGround;
final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
entityHeadLookPacket.entityId = getEntityId();
entityHeadLookPacket.yaw = position.getYaw();
entityHeadLookPacket.yaw = position.yaw();
if (clientSide) {
sendPacketToViewers(entityHeadLookPacket);
@ -736,12 +697,12 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
if (PlayerUtils.isNettyClient(this) && !clientSide) {
final PlayerPositionAndLookPacket playerPositionAndLookPacket = new PlayerPositionAndLookPacket();
playerPositionAndLookPacket.flags = 0b111;
playerPositionAndLookPacket.position = position.clone().subtract(lastSyncedPosition.getX(), lastSyncedPosition.getY(), lastSyncedPosition.getZ());
playerPositionAndLookPacket.position = position.sub(lastSyncedPosition);
playerPositionAndLookPacket.teleportId = ((Player) this).getNextTeleportId();
((Player) this).getPlayerConnection().sendPacket(playerPositionAndLookPacket);
}
lastSyncedPosition.set(position);
this.lastSyncedPosition = position;
}
/**
@ -893,25 +854,25 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* @param spawnPosition the spawn position for the entity.
* @throws IllegalStateException if {@code instance} has not been registered in {@link InstanceManager}
*/
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
public void setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) {
Check.stateCondition(!instance.isRegistered(),
"Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance");
if (this.instance != null) {
this.instance.UNSAFE_removeEntity(this);
}
this.position.set(spawnPosition);
this.lastPosition.set(position);
this.position = spawnPosition;
this.isActive = true;
this.instance = instance;
refreshCurrentChunk(instance.getChunkAt(position.getX(), position.getZ()));
refreshCurrentChunk(instance.getChunkAt(position));
instance.UNSAFE_addEntity(this);
spawn();
EventDispatcher.call(new EntitySpawnEvent(this, instance));
}
public void setInstance(@NotNull Instance instance, @NotNull Point spawnPosition) {
setInstance(instance, Pos.fromPoint(spawnPosition));
}
/**
* Changes the entity instance.
*
@ -928,8 +889,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
*
* @return the entity current velocity
*/
@NotNull
public Vector getVelocity() {
public @NotNull Vec getVelocity() {
return velocity;
}
@ -940,10 +900,10 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
*
* @param velocity the new entity velocity
*/
public void setVelocity(@NotNull Vector velocity) {
public void setVelocity(@NotNull Vec velocity) {
EntityVelocityEvent entityVelocityEvent = new EntityVelocityEvent(this, velocity);
EventDispatcher.callCancellable(entityVelocityEvent, () -> {
this.velocity.copy(entityVelocityEvent.getVelocity());
this.velocity = entityVelocityEvent.getVelocity();
sendPacketToViewersAndSelf(getVelocityPacket());
});
}
@ -954,7 +914,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* @return true if velocity is not set to 0
*/
public boolean hasVelocity() {
return !velocity.isZero();
return !velocity.samePoint(Vec.ZERO);
}
/**
@ -1003,7 +963,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* @return the distance between this and {@code entity}
*/
public double getDistance(@NotNull Entity entity) {
return getPosition().getDistance(entity.getPosition());
return getPosition().distance(entity.getPosition());
}
/**
@ -1013,7 +973,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* @return the distance squared between this and {@code entity}
*/
public double getDistanceSquared(@NotNull Entity entity) {
return getPosition().getDistanceSquared(entity.getPosition());
return getPosition().distanceSquared(entity.getPosition());
}
/**
@ -1321,42 +1281,56 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
this.entityMeta.setHasNoGravity(noGravity);
}
/**
* Updates internal fields and sends updates.
*
* @param position the new position
* @see #sendPositionUpdate(boolean)
*/
@ApiStatus.Internal
public void refreshPosition(@NotNull final Pos position, boolean ignoreView) {
if (!position.samePoint(this.position)) {
refreshCoordinate(position);
}
if (!ignoreView) {
this.position = position;
} else {
this.position = this.position.withCoord(position);
}
sendPositionUpdate(true);
}
@ApiStatus.Internal
public void refreshPosition(@NotNull final Pos position) {
refreshPosition(position, false);
}
/**
* Used to refresh the entity and its passengers position
* - put the entity in the right instance chunk
* - update the viewable chunks (load and unload)
* - add/remove players from the viewers list if {@link #isAutoViewable()} is enabled
* <p>
* WARNING: unsafe, should only be used internally in Minestom. Use {@link #teleport(Position)} instead.
* WARNING: unsafe, should only be used internally in Minestom. Use {@link #teleport(Pos)} instead.
*
* @param x new position X
* @param y new position Y
* @param z new position Z
* @param newPosition the new position
*/
private void refreshPosition(double x, double y, double z) {
position.setX(x);
position.setY(y);
position.setZ(z);
private void refreshCoordinate(Point newPosition) {
if (hasPassenger()) {
for (Entity passenger : getPassengers()) {
passenger.refreshPosition(x, y, z);
passenger.refreshCoordinate(newPosition);
}
}
final Instance instance = getInstance();
if (instance != null) {
final int lastChunkX = currentChunk.getChunkX();
final int lastChunkZ = currentChunk.getChunkZ();
final int newChunkX = ChunkUtils.getChunkCoordinate(x);
final int newChunkZ = ChunkUtils.getChunkCoordinate(z);
final int newChunkX = ChunkUtils.getChunkCoordinate(newPosition.x());
final int newChunkZ = ChunkUtils.getChunkCoordinate(newPosition.z());
if (lastChunkX != newChunkX || lastChunkZ != newChunkZ) {
// Entity moved in a new chunk
final Chunk newChunk = instance.getChunk(newChunkX, newChunkZ);
Check.notNull(newChunk, "The entity {0} tried to move in an unloaded chunk at {1};{2}", getEntityId(), x, z);
Check.notNull(newChunk, "The entity {0} tried to move in an unloaded chunk at {1}", getEntityId(), newPosition);
instance.UNSAFE_switchEntityChunk(this, currentChunk, newChunk);
if (this instanceof Player) {
// Refresh player view
@ -1364,45 +1338,9 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
player.refreshVisibleChunks(newChunk);
player.refreshVisibleEntities(newChunk);
}
refreshCurrentChunk(newChunk);
}
}
this.lastPosition.setX(position.getX());
this.lastPosition.setY(position.getY());
this.lastPosition.setZ(position.getZ());
}
/**
* Updates internal fields and sends updates
*
* @param position the new position
* @see #refreshPosition(double, double, double)
* @see #refreshView(float, float)
* @see #sendPositionUpdate(boolean)
*/
@ApiStatus.Internal
public void refreshPosition(@NotNull final Position position) {
if (!position.isSimilar(this.position))
refreshPosition(position.getX(), position.getY(), position.getZ());
refreshView(position.getYaw(), position.getPitch());
sendPositionUpdate(true);
}
/**
* Updates the entity view internally.
* <p>
* Warning: you probably want to use {@link #setView(float, float)}.
*
* @param yaw the yaw
* @param pitch the pitch
*/
private void refreshView(final float yaw, final float pitch) {
lastPosition.setYaw(position.getYaw());
lastPosition.setPitch(position.getPitch());
position.setYaw(yaw);
position.setPitch(pitch);
}
/**
@ -1410,8 +1348,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
*
* @return the current position of the entity
*/
@NotNull
public Position getPosition() {
public @NotNull Pos getPosition() {
return position;
}
@ -1536,19 +1473,17 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
return scheduledRemoveTime != 0;
}
@NotNull
protected Vector getVelocityForPacket() {
return this.velocity.clone().multiply(8000f / MinecraftServer.TICK_PER_SECOND);
protected @NotNull Vec getVelocityForPacket() {
return this.velocity.mul(8000f / MinecraftServer.TICK_PER_SECOND);
}
@NotNull
protected EntityVelocityPacket getVelocityPacket() {
protected @NotNull EntityVelocityPacket getVelocityPacket() {
EntityVelocityPacket velocityPacket = new EntityVelocityPacket();
velocityPacket.entityId = getEntityId();
Vector velocity = getVelocityForPacket();
velocityPacket.velocityX = (short) velocity.getX();
velocityPacket.velocityY = (short) velocity.getY();
velocityPacket.velocityZ = (short) velocity.getZ();
Vec velocity = getVelocityForPacket();
velocityPacket.velocityX = (short) velocity.x();
velocityPacket.velocityY = (short) velocity.y();
velocityPacket.velocityZ = (short) velocity.z();
return velocityPacket;
}
@ -1576,15 +1511,14 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
*/
@ApiStatus.Internal
protected void synchronizePosition(boolean includeSelf) {
final Position pos = position.clone();
final EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket();
entityTeleportPacket.entityId = getEntityId();
entityTeleportPacket.position = pos;
entityTeleportPacket.position = position;
entityTeleportPacket.onGround = isOnGround();
sendPacketToViewers(entityTeleportPacket);
this.lastAbsoluteSynchronizationTime = System.currentTimeMillis();
this.lastSyncedPosition.set(pos);
this.lastSyncedPosition = position;
}
/**
@ -1738,10 +1672,13 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
public void takeKnockback(final float strength, final double x, final double z) {
if (strength > 0) {
//TODO check possible side effects of unnatural TPS (other than 20TPS)
final Vector velocityModifier = new Vector(x, 0d, z).normalize().multiply(strength * MinecraftServer.TICK_PER_SECOND / 2);
this.velocity.setX(velocity.getX() / 2d - velocityModifier.getX());
this.velocity.setY(onGround ? Math.min(.4d, velocity.getY() / 2d + strength) * MinecraftServer.TICK_PER_SECOND : velocity.getY());
this.velocity.setZ(velocity.getZ() / 2d - velocityModifier.getZ());
final Vec velocityModifier = new Vec(x, z)
.normalize()
.mul(strength * MinecraftServer.TICK_PER_SECOND / 2);
setVelocity(new Vec(velocity.x() / 2d - velocityModifier.x(),
onGround ? Math.min(.4d, velocity.y() / 2d + strength) * MinecraftServer.TICK_PER_SECOND : velocity.y(),
velocity.z() / 2d - velocityModifier.z()
));
}
}

View File

@ -2,6 +2,7 @@ package net.minestom.server.entity;
import com.extollit.gaming.ai.path.HydrazinePathFinder;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.ai.EntityAI;
import net.minestom.server.entity.ai.EntityAIGroup;
import net.minestom.server.entity.pathfinding.NavigableEntity;
@ -9,7 +10,6 @@ import net.minestom.server.entity.pathfinding.Navigator;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -42,20 +42,6 @@ public class EntityCreature extends LivingEntity implements NavigableEntity, Ent
this(entityType, UUID.randomUUID());
}
@Deprecated
public EntityCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
heal();
}
@Deprecated
public EntityCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition, @Nullable Instance instance) {
this(entityType, spawnPosition);
if (instance != null) {
setInstance(instance);
}
}
@Override
public void update(long time) {
// AI
@ -69,7 +55,7 @@ public class EntityCreature extends LivingEntity implements NavigableEntity, Ent
}
@Override
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
public void setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) {
this.navigator.setPathFinder(new HydrazinePathFinder(navigator.getPathingEntity(), instance.getInstanceSpace()));
super.setInstance(instance, spawnPosition);

View File

@ -1,8 +1,5 @@
package net.minestom.server.entity;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.entity.metadata.ProjectileMeta;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityAttackEvent;
@ -10,9 +7,9 @@ import net.minestom.server.event.entity.EntityShootEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -35,13 +32,6 @@ public class EntityProjectile extends Entity {
setup();
}
@Deprecated
public EntityProjectile(@Nullable Entity shooter, @NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
this.shooter = shooter;
setup();
}
private void setup() {
super.hasPhysics = false;
if (getEntityMeta() instanceof ProjectileMeta) {
@ -70,21 +60,21 @@ public class EntityProjectile extends Entity {
}
public void shoot(Position to, double power, double spread) {
public void shoot(Point to, double power, double spread) {
EntityShootEvent shootEvent = new EntityShootEvent(this.shooter, this, to, power, spread);
EventDispatcher.call(shootEvent);
if (shootEvent.isCancelled()) {
remove();
return;
}
Position from = this.shooter.getPosition().clone().add(0D, this.shooter.getEyeHeight(), 0D);
final var from = this.shooter.getPosition().add(0D, this.shooter.getEyeHeight(), 0D);
shoot(from, to, shootEvent.getPower(), shootEvent.getSpread());
}
private void shoot(@NotNull Position from, @NotNull Position to, double power, double spread) {
double dx = to.getX() - from.getX();
double dy = to.getY() - from.getY();
double dz = to.getZ() - from.getZ();
private void shoot(@NotNull Point from, @NotNull Point to, double power, double spread) {
double dx = to.x() - from.x();
double dy = to.y() - from.y();
double dz = to.z() - from.z();
double xzLength = Math.sqrt(dx * dx + dz * dz);
dy += xzLength * 0.20000000298023224D;
@ -97,10 +87,9 @@ public class EntityProjectile extends Entity {
dx += random.nextGaussian() * spread;
dy += random.nextGaussian() * spread;
dz += random.nextGaussian() * spread;
super.velocity.setX(dx);
super.velocity.setY(dy);
super.velocity.setZ(dz);
super.velocity.multiply(20 * power);
final double mul = 20 * power;
this.velocity = new Vec(dx * mul, dy * mul, dz * mul);
setView(
(float) Math.toDegrees(Math.atan2(dx, dz)),
(float) Math.toDegrees(Math.atan2(dy, Math.sqrt(dx * dx + dz * dz)))
@ -109,15 +98,15 @@ public class EntityProjectile extends Entity {
@Override
public void tick(long time) {
Position posBefore = getPosition().clone();
final var posBefore = getPosition();
super.tick(time);
Position posNow = getPosition().clone();
final var posNow = getPosition();
if (isStuck(posBefore, posNow)) {
if (super.onGround) {
return;
}
super.onGround = true;
getVelocity().zero();
this.velocity = Vec.ZERO;
sendPacketToViewersAndSelf(getVelocityPacket());
setNoGravity(true);
onStuck();
@ -139,8 +128,8 @@ public class EntityProjectile extends Entity {
* @return if an arrow is stuck in block / hit an entity.
*/
@SuppressWarnings("ConstantConditions")
private boolean isStuck(Position pos, Position posNow) {
if (pos.isSimilar(posNow)) {
private boolean isStuck(Pos pos, Pos posNow) {
if (pos.samePoint(posNow)) {
return true;
}
@ -153,25 +142,21 @@ public class EntityProjectile extends Entity {
For each point we will be checking blocks and entities we're in.
*/
double part = .25D; // half of the bounding box
Vector dir = posNow.toVector().subtract(pos.toVector());
final var dir = posNow.sub(pos).asVec();
int parts = (int) Math.ceil(dir.length() / part);
Position direction = dir.normalize().multiply(part).toPosition();
final var direction = dir.normalize().mul(part).asPosition();
for (int i = 0; i < parts; ++i) {
// If we're at last part, we can't just add another direction-vector, because we can exceed end point.
if (i == parts - 1) {
pos.setX(posNow.getX());
pos.setY(posNow.getY());
pos.setZ(posNow.getZ());
pos = posNow;
} else {
pos.add(direction);
pos = pos.add(direction);
}
BlockPosition bpos = pos.toBlockPosition();
Block block = instance.getBlock(bpos.getX(), bpos.getY() - 1, bpos.getZ());
Block block = instance.getBlock(pos.sub(0, 1, 0));
if (!block.isAir() && !block.isLiquid()) {
teleport(pos);
return true;
}
Chunk currentChunk = instance.getChunkAt(pos);
if (currentChunk != chunk) {
chunk = currentChunk;
@ -187,8 +172,9 @@ public class EntityProjectile extends Entity {
if (getAliveTicks() < 3) {
continue;
}
final Pos finalPos = pos;
Optional<Entity> victimOptional = entities.stream()
.filter(entity -> entity.getBoundingBox().intersect(pos.getX(), pos.getY(), pos.getZ()))
.filter(entity -> entity.getBoundingBox().intersect(finalPos))
.findAny();
if (victimOptional.isPresent()) {
LivingEntity victim = (LivingEntity) victimOptional.get();
@ -200,5 +186,4 @@ public class EntityProjectile extends Entity {
}
return false;
}
}

View File

@ -1,12 +1,11 @@
package net.minestom.server.entity;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.metadata.ObjectDataProvider;
import net.minestom.server.entity.metadata.other.ExperienceOrbMeta;
import net.minestom.server.entity.metadata.other.PaintingMeta;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Vector;
public enum EntitySpawnType {
BASE {
@ -21,10 +20,10 @@ public enum EntitySpawnType {
ObjectDataProvider objectDataProvider = (ObjectDataProvider) entity.getEntityMeta();
packet.data = objectDataProvider.getObjectData();
if (objectDataProvider.requiresVelocityPacketAtSpawn()) {
Vector velocity = entity.getVelocityForPacket();
packet.velocityX = (short) velocity.getX();
packet.velocityY = (short) velocity.getY();
packet.velocityZ = (short) velocity.getZ();
final var velocity = entity.getVelocityForPacket();
packet.velocityX = (short) velocity.x();
packet.velocityY = (short) velocity.y();
packet.velocityZ = (short) velocity.z();
}
}
return packet;
@ -38,11 +37,11 @@ public enum EntitySpawnType {
packet.entityUuid = entity.getUuid();
packet.entityType = entity.getEntityType().ordinal();
packet.position = entity.getPosition();
packet.headPitch = entity.getPosition().getPitch();
Vector velocity = entity.getVelocityForPacket();
packet.velocityX = (short) velocity.getX();
packet.velocityY = (short) velocity.getY();
packet.velocityZ = (short) velocity.getZ();
packet.headPitch = entity.getPosition().pitch();
final var velocity = entity.getVelocityForPacket();
packet.velocityX = (short) velocity.x();
packet.velocityY = (short) velocity.y();
packet.velocityZ = (short) velocity.z();
return packet;
}
},
@ -78,7 +77,7 @@ public enum EntitySpawnType {
if (entity.getEntityMeta() instanceof PaintingMeta) {
PaintingMeta paintingMeta = (PaintingMeta) entity.getEntityMeta();
packet.motive = paintingMeta.getMotive().ordinal();
packet.position = new BlockPosition(
packet.position = new Vec(
Math.max(0, (paintingMeta.getMotive().getWidth() >> 1) - 1),
paintingMeta.getMotive().getHeight() >> 1,
0
@ -98,12 +97,12 @@ public enum EntitySpawnType {
break;
}
} else {
packet.position = new BlockPosition(0, 0, 0);
packet.position = Vec.ZERO;
}
return packet;
}
};
public abstract ServerPacket getSpawnPacket(Entity entity);
}

View File

@ -1,10 +1,6 @@
package net.minestom.server.entity;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import net.minestom.server.coordinate.Vec;
import java.util.Comparator;
@ -14,22 +10,13 @@ public class ExperienceOrb extends Entity {
private Player target;
private long lastTargetUpdateTick;
public ExperienceOrb(short experienceCount, @NotNull Position spawnPosition) {
super(EntityType.EXPERIENCE_ORB, spawnPosition);
public ExperienceOrb(short experienceCount) {
super(EntityType.EXPERIENCE_ORB);
setBoundingBox(0.5f, 0.5f, 0.5f);
//todo vanilla sets random velocity here?
this.experienceCount = experienceCount;
}
public ExperienceOrb(short experienceCount, @NotNull Position spawnPosition, @Nullable Instance instance) {
this(experienceCount, spawnPosition);
if (instance != null) {
setInstance(instance);
}
}
@Override
public void update(long time) {
@ -44,7 +31,7 @@ public class ExperienceOrb extends Entity {
double d = 8.0;
if (lastTargetUpdateTick < time - 20 + getEntityId() % 100) {
if (target == null || target.getPosition().getDistanceSquared(getPosition()) > 64) {
if (target == null || target.getPosition().distanceSquared(getPosition()) > 64) {
this.target = getClosestPlayer(this, 8);
}
@ -56,13 +43,13 @@ public class ExperienceOrb extends Entity {
}
if (target != null) {
Position pos = getPosition();
Position targetPos = target.getPosition();
Vector toTarget = new Vector(targetPos.getX() - pos.getX(), targetPos.getY() + (target.getEyeHeight() / 2) - pos.getY(), targetPos.getZ() - pos.getZ());
final var pos = getPosition();
final var targetPos = target.getPosition();
final Vec toTarget = new Vec(targetPos.x() - pos.x(), targetPos.y() + (target.getEyeHeight() / 2) - pos.y(), targetPos.z() - pos.z());
double e = toTarget.length(); //could really be lengthSquared
if (e < 8) {
double f = 1 - (e / 8);
setVelocity(getVelocity().add(toTarget.normalize().multiply(f * f * 0.1)));
setVelocity(getVelocity().add(toTarget.normalize().mul(f * f * 0.1)));
}
}
@ -74,9 +61,10 @@ public class ExperienceOrb extends Entity {
}
// apply slipperiness
setVelocity(getVelocity().multiply(new Vector(g, 0.98f, g)));
if (isOnGround())
setVelocity(getVelocity().multiply(new Vector(1, -0.9f, 1)));
setVelocity(getVelocity().mul(new Vec(g, 0.98f, g)));
if (isOnGround()) {
setVelocity(getVelocity().mul(new Vec(1, -0.9f, 1)));
}
}
@Override

View File

@ -4,10 +4,8 @@ import net.minestom.server.entity.metadata.item.ItemEntityMeta;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityItemMergeEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.StackingRule;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull;
@ -41,20 +39,12 @@ public class ItemEntity extends Entity {
private long spawnTime;
private long pickupDelay;
public ItemEntity(@NotNull ItemStack itemStack, @NotNull Position spawnPosition) {
super(EntityType.ITEM, spawnPosition);
public ItemEntity(@NotNull ItemStack itemStack) {
super(EntityType.ITEM);
setItemStack(itemStack);
setBoundingBox(0.25f, 0.25f, 0.25f);
}
public ItemEntity(@NotNull ItemStack itemStack, @NotNull Position spawnPosition, @Nullable Instance instance) {
this(itemStack, spawnPosition);
if (instance != null) {
setInstance(instance);
}
}
/**
* Gets the update option for the merging feature.
*
@ -70,7 +60,6 @@ public class ItemEntity extends Entity {
* Can be set to null to entirely remove the delay.
*
* @param mergeUpdateOption the new merge update option
*
* @deprecated Replaced by {@link #setMergeDelay(Duration)}
*/
@SuppressWarnings("removal")
@ -239,7 +228,7 @@ public class ItemEntity extends Entity {
/**
* Sets the pickup delay of the ItemEntity.
*
* @param delay the pickup delay
* @param delay the pickup delay
* @param temporalUnit the unit of the delay
*/
public void setPickupDelay(long delay, @NotNull TemporalUnit temporalUnit) {
@ -249,7 +238,7 @@ public class ItemEntity extends Entity {
/**
* Sets the pickup delay of the ItemEntity.
*
* @param delay the pickup delay
* @param delay the pickup delay
*/
public void setPickupDelay(Duration delay) {
this.pickupDelay = delay.toMillis();

View File

@ -5,6 +5,8 @@ import net.minestom.server.attribute.Attribute;
import net.minestom.server.attribute.AttributeInstance;
import net.minestom.server.attribute.Attributes;
import net.minestom.server.collision.BoundingBox;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.metadata.LivingEntityMeta;
import net.minestom.server.event.EventDispatcher;
@ -25,9 +27,6 @@ import net.minestom.server.network.packet.server.play.SoundEffectPacket;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.scoreboard.Team;
import net.minestom.server.sound.SoundEvent;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.block.BlockIterator;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit;
@ -90,7 +89,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
* Constructor which allows to specify an UUID. Only use if you know what you are doing!
*/
public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid) {
this(entityType, uuid, new Position());
super(entityType, uuid);
initEquipments();
}
@ -98,20 +97,6 @@ public class LivingEntity extends Entity implements EquipmentHandler {
this(entityType, UUID.randomUUID());
}
/**
* Constructor which allows to specify an UUID. Only use if you know what you are doing!
*/
@Deprecated
public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) {
super(entityType, uuid, spawnPosition);
initEquipments();
}
@Deprecated
public LivingEntity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
this(entityType, UUID.randomUUID(), spawnPosition);
}
private void initEquipments() {
this.mainHandItem = ItemStack.AIR;
this.offHandItem = ItemStack.AIR;
@ -300,7 +285,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
setHealth(0);
// Reset velocity
velocity.zero();
this.velocity = Vec.ZERO;
// Remove passengers if any
if (hasPassenger()) {
@ -323,8 +308,8 @@ public class LivingEntity extends Entity implements EquipmentHandler {
/**
* Sets fire to this entity for a given duration.
*
* @param duration duration of the effect
* @param temporalUnit unit used to express the duration
* @param duration duration of the effect
* @param temporalUnit unit used to express the duration
* @see #setOnFire(boolean) if you want it to be permanent without any event callback
*/
public void setFireForDuration(int duration, TemporalUnit temporalUnit) {
@ -732,16 +717,16 @@ public class LivingEntity extends Entity implements EquipmentHandler {
}
/**
* Gets the line of sight in {@link BlockPosition} of the entity.
* Gets the line of sight of the entity.
*
* @param maxDistance The max distance to scan
* @return A list of {@link BlockPosition} in this entities line of sight
* @return A list of {@link Point poiints} in this entities line of sight
*/
public List<BlockPosition> getLineOfSight(int maxDistance) {
List<BlockPosition> blocks = new ArrayList<>();
Iterator<BlockPosition> it = new BlockIterator(this, maxDistance);
public List<Point> getLineOfSight(int maxDistance) {
List<Point> blocks = new ArrayList<>();
Iterator<Point> it = new BlockIterator(this, maxDistance);
while (it.hasNext()) {
BlockPosition position = it.next();
final Point position = it.next();
if (!getInstance().getBlock(position).isAir()) blocks.add(position);
}
return blocks;
@ -756,12 +741,12 @@ public class LivingEntity extends Entity implements EquipmentHandler {
* @return if the current entity has line of sight to the given one.
*/
public boolean hasLineOfSight(Entity entity) {
Vector start = getPosition().toVector().add(0D, getEyeHeight(), 0D);
Vector end = entity.getPosition().toVector().add(0D, getEyeHeight(), 0D);
Vector direction = end.subtract(start);
int maxDistance = (int) Math.ceil(direction.length());
final var start = getPosition().asVec().add(0D, getEyeHeight(), 0D);
final var end = entity.getPosition().asVec().add(0D, getEyeHeight(), 0D);
final var direction = end.sub(start);
final int maxDistance = (int) Math.ceil(direction.length());
Iterator<BlockPosition> it = new BlockIterator(start, direction.normalize(), 0D, maxDistance);
Iterator<Point> it = new BlockIterator(start, direction.normalize(), 0D, maxDistance);
while (it.hasNext()) {
Block block = getInstance().getBlock(it.next());
if (!block.isAir() && !block.isLiquid()) {
@ -772,16 +757,16 @@ public class LivingEntity extends Entity implements EquipmentHandler {
}
/**
* Gets the target (not-air) {@link BlockPosition} of the entity.
* Gets the target (not-air) block position of the entity.
*
* @param maxDistance The max distance to scan before returning null
* @return The {@link BlockPosition} targeted by this entity, null if non are found
* @return The block position targeted by this entity, null if non are found
*/
public BlockPosition getTargetBlockPosition(int maxDistance) {
Iterator<BlockPosition> it = new BlockIterator(this, maxDistance);
public Point getTargetBlockPosition(int maxDistance) {
Iterator<Point> it = new BlockIterator(this, maxDistance);
while (it.hasNext()) {
BlockPosition position = it.next();
if (getInstance().getBlock(position) != Block.AIR) return position;
final Point position = it.next();
if (!getInstance().getBlock(position).isAir()) return position;
}
return null;
}
@ -804,8 +789,8 @@ public class LivingEntity extends Entity implements EquipmentHandler {
* Note: The strength is reduced based on knockback resistance
*
* @param strength the strength of the knockback, 0.4 is the vanilla value for a bare hand hit
* @param x knockback on x axle, for default knockback use the following formula <pre>sin(attacker.yaw * (pi/180))</pre>
* @param z knockback on z axle, for default knockback use the following formula <pre>-cos(attacker.yaw * (pi/180))</pre>
* @param x knockback on x axle, for default knockback use the following formula <pre>sin(attacker.yaw * (pi/180))</pre>
* @param z knockback on z axle, for default knockback use the following formula <pre>-cos(attacker.yaw * (pi/180))</pre>
*/
@Override
public void takeKnockback(float strength, final double x, final double z) {

View File

@ -4,16 +4,15 @@ import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.EntityMetaDataPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Direction;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.binary.Readable;
import net.minestom.server.utils.binary.Writeable;
import net.minestom.server.utils.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBT;
@ -98,12 +97,12 @@ public class Metadata {
return new Value<>(TYPE_BOOLEAN, value, writer -> writer.writeBoolean(value), BinaryReader::readBoolean);
}
public static Value<Vector> Rotation(@NotNull Vector value) {
public static Value<Point> Rotation(@NotNull Point value) {
return new Value<>(TYPE_ROTATION, value, writer -> {
writer.writeFloat((float) value.getX());
writer.writeFloat((float) value.getY());
writer.writeFloat((float) value.getZ());
}, reader -> new Vector(reader.readFloat(), reader.readFloat(), reader.readFloat()));
writer.writeFloat((float) value.x());
writer.writeFloat((float) value.y());
writer.writeFloat((float) value.z());
}, reader -> new Vec(reader.readFloat(), reader.readFloat(), reader.readFloat()));
}
public static Value<Point> Position(@NotNull Point value) {
@ -339,7 +338,7 @@ public class Metadata {
case TYPE_STRING:
return (Value<T>) String("");
case TYPE_CHAT:
return (Value<T>) Chat(ColoredText.of(""));
return (Value<T>) Chat(Component.empty());
case TYPE_OPTCHAT:
return (Value<T>) OptChat((Component) null);
case TYPE_SLOT:
@ -347,9 +346,9 @@ public class Metadata {
case TYPE_BOOLEAN:
return (Value<T>) Boolean(false);
case TYPE_ROTATION:
return (Value<T>) Rotation(new Vector());
return (Value<T>) Rotation(Vec.ZERO);
case TYPE_POSITION:
return (Value<T>) Position(new BlockPosition(0, 0, 0));
return (Value<T>) Position(Vec.ZERO);
case TYPE_OPTPOSITION:
return (Value<T>) OptPosition(null);
case TYPE_DIRECTION:

View File

@ -26,6 +26,9 @@ import net.minestom.server.chat.JsonMessage;
import net.minestom.server.collision.BoundingBox;
import net.minestom.server.command.CommandManager;
import net.minestom.server.command.CommandSender;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.effects.Effects;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.fakeplayer.FakePlayer;
@ -130,7 +133,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
private byte heldSlot;
private Position respawnPoint;
private Pos respawnPoint;
private int food;
private float foodSaturation;
@ -179,7 +182,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
setBoundingBox(0.6f, 1.8f, 0.6f);
setRespawnPoint(new Position(0, 0, 0));
setRespawnPoint(Pos.ZERO);
this.settings = new PlayerSettings();
this.inventory = new PlayerInventory(this);
@ -520,9 +523,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
* @param spawnPosition the new position of the player
*/
@Override
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
public void setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) {
Check.argCondition(this.instance == instance, "Instance should be different than the current one");
// true if the chunks need to be sent to the client, can be false if the instances share the same chunks (eg SharedInstance)
final boolean needWorldRefresh = !InstanceUtils.areLinked(this.instance, instance) ||
!spawnPosition.inSameChunk(this.position);
@ -557,7 +559,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
* if the player is not in any instance).
*
* @param instance the new player instance
* @see #setInstance(Instance, Position)
* @see #setInstance(Instance, Pos)
*/
@Override
public void setInstance(@NotNull Instance instance) {
@ -569,14 +571,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
* <p>
* Does add the player to {@code instance}, remove all viewable entities and call {@link PlayerSpawnEvent}.
* <p>
* UNSAFE: only called with {@link #setInstance(Instance, Position)}.
* UNSAFE: only called with {@link #setInstance(Instance, Pos)}.
*
* @param spawnPosition the position to teleport the player
* @param firstSpawn true if this is the player first spawn
* @param updateChunks true if chunks should be refreshed, false if the new instance shares the same
* chunks
*/
private void spawnPlayer(@NotNull Instance instance, @NotNull Position spawnPosition,
private void spawnPlayer(@NotNull Instance instance, @NotNull Pos spawnPosition,
boolean firstSpawn, boolean dimensionChange, boolean updateChunks) {
if (!firstSpawn) {
// Player instance changed, clear current viewable collections
@ -699,17 +701,6 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
playerConnection.sendPacket(soundEffectPacket);
}
/**
* Plays a sound from the {@link SoundEvent} enum.
*
* @see #playSound(SoundEvent, SoundCategory, int, int, int, float, float)
* @deprecated Use {@link #playSound(net.kyori.adventure.sound.Sound, double, double, double)}
*/
@Deprecated
public void playSound(@NotNull SoundEvent sound, @NotNull SoundCategory soundCategory, BlockPosition position, float volume, float pitch) {
playSound(sound, soundCategory, position.getX(), position.getY(), position.getZ(), volume, pitch);
}
/**
* Plays a sound from an identifier (represents a custom sound in a resource pack).
*
@ -735,17 +726,6 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
playerConnection.sendPacket(namedSoundEffectPacket);
}
/**
* Plays a sound from an identifier (represents a custom sound in a resource pack).
*
* @see #playSound(String, SoundCategory, int, int, int, float, float)
* @deprecated Use {@link #playSound(net.kyori.adventure.sound.Sound, double, double, double)}
*/
@Deprecated
public void playSound(@NotNull String identifier, @NotNull SoundCategory soundCategory, BlockPosition position, float volume, float pitch) {
playSound(identifier, soundCategory, position.getX(), position.getY(), position.getZ(), volume, pitch);
}
/**
* Plays a sound directly to the player (constant volume).
*
@ -768,7 +748,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
@Override
public void playSound(@NotNull Sound sound) {
this.playSound(sound, this.position.getX(), this.position.getY(), this.position.getZ());
this.playSound(sound, this.position.x(), this.position.y(), this.position.z());
}
@Override
@ -807,7 +787,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
public void playEffect(@NotNull Effects effect, int x, int y, int z, int data, boolean disableRelativeVolume) {
EffectPacket packet = new EffectPacket();
packet.effectId = effect.getId();
packet.position = new BlockPosition(x, y, z);
packet.position = new Vec(x, y, z);
packet.data = data;
packet.disableRelativeVolume = disableRelativeVolume;
playerConnection.sendPacket(packet);
@ -1294,14 +1274,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
facePosition(facePoint, entity.getPosition(), entity, targetPoint);
}
private void facePosition(@NotNull FacePoint facePoint, @NotNull Position targetPosition,
private void facePosition(@NotNull FacePoint facePoint, @NotNull Point targetPosition,
@Nullable Entity entity, @Nullable FacePoint targetPoint) {
FacePlayerPacket facePlayerPacket = new FacePlayerPacket();
facePlayerPacket.entityFacePosition = facePoint == FacePoint.EYE ?
FacePlayerPacket.FacePosition.EYES : FacePlayerPacket.FacePosition.FEET;
facePlayerPacket.targetX = targetPosition.getX();
facePlayerPacket.targetY = targetPosition.getY();
facePlayerPacket.targetZ = targetPosition.getZ();
facePlayerPacket.targetX = targetPosition.x();
facePlayerPacket.targetY = targetPosition.y();
facePlayerPacket.targetZ = targetPosition.z();
if (entity != null) {
facePlayerPacket.entityId = entity.getEntityId();
facePlayerPacket.entityFacePosition = targetPoint == FacePoint.EYE ?
@ -1329,13 +1309,12 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
/**
* Used to retrieve the default spawn point.
* <p>
* Can be altered by the {@link PlayerRespawnEvent#setRespawnPosition(Position)}.
* Can be altered by the {@link PlayerRespawnEvent#setRespawnPosition(Pos)}.
*
* @return a copy of the default respawn point
*/
@NotNull
public Position getRespawnPoint() {
return respawnPoint.clone();
public @NotNull Pos getRespawnPoint() {
return respawnPoint;
}
/**
@ -1343,7 +1322,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
*
* @param respawnPoint the player respawn point
*/
public void setRespawnPoint(@NotNull Position respawnPoint) {
public void setRespawnPoint(@NotNull Pos respawnPoint) {
this.respawnPoint = respawnPoint;
}
@ -1365,8 +1344,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
{
// Send new chunks
final BlockPosition pos = position.toBlockPosition();
final Chunk chunk = instance.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
final Chunk chunk = instance.getChunkAt(position);
Check.notNull(chunk, "Tried to interact with an unloaded chunk.");
refreshVisibleChunks(chunk);
}
@ -1903,7 +1881,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
protected void synchronizePosition(boolean includeSelf) {
if (includeSelf) {
final PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket();
positionAndLookPacket.position = position.clone();
positionAndLookPacket.position = position;
positionAndLookPacket.flags = 0x00;
positionAndLookPacket.teleportId = teleportId.incrementAndGet();
playerConnection.sendPacket(positionAndLookPacket);
@ -2324,7 +2302,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
entityHeadLookPacket.entityId = getEntityId();
entityHeadLookPacket.yaw = position.getYaw();
entityHeadLookPacket.yaw = position.yaw();
connection.sendPacket(entityHeadLookPacket);
}

View File

@ -2,11 +2,10 @@ package net.minestom.server.entity.ai.goal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityProjectile;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.entity.pathfinding.Navigator;
import net.minestom.server.entity.EntityProjectile;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.utils.validate.Check;
@ -175,7 +174,7 @@ public class CombinedAttackGoal extends GoalSelector {
if (!Cooldown.hasCooldown(time, this.lastAttack, this.rangedDelay)) {
if (this.entityCreature.hasLineOfSight(target)) {
// If target is on line of entity sight, ranged attack can be performed
Position to = target.getPosition().clone().add(0D, target.getEyeHeight(), 0D);
final var to = target.getPosition().add(0D, target.getEyeHeight(), 0D);
Function<Entity, EntityProjectile> projectileGenerator = this.projectileGenerator;
if (projectileGenerator == null) {
@ -193,7 +192,7 @@ public class CombinedAttackGoal extends GoalSelector {
}
}
Navigator navigator = this.entityCreature.getNavigator();
Position pathPosition = navigator.getPathPosition();
final var pathPosition = navigator.getPathPosition();
// If we don't want to come close and we're already within desirable range, no movement is needed.
if (!comeClose && distanceSquared <= this.desirableRangeSquared) {
if (pathPosition != null) {
@ -202,8 +201,8 @@ public class CombinedAttackGoal extends GoalSelector {
return;
}
// Otherwise going to the target.
Position targetPosition = target.getPosition();
if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) {
final var targetPosition = target.getPosition();
if (pathPosition == null || !pathPosition.samePoint(targetPosition)) {
if (this.cooldown.isReady(time)) {
this.cooldown.refreshLastUpdate(time);
navigator.setPathTo(targetPosition);

View File

@ -1,95 +0,0 @@
package net.minestom.server.entity.ai.goal;
import it.unimi.dsi.fastutil.shorts.Short2ShortArrayMap;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
public class EatBlockGoal extends GoalSelector {
private static final Random RANDOM = new Random();
private final Short2ShortArrayMap eatBelowMap;
private final Short2ShortArrayMap eatInMap;
private final int chancePerTick;
private int eatAnimationTick;
/**
* @param entityCreature Creature that should eat a block.
* @param eatInMap Map containing the block IDs that the entity can eat (when inside the block) and the block ID of the replacement block.
* @param eatBelowMap Map containing block IDs that the entity can eat (when above the block) and the block ID of the replacement block.
* @param chancePerTick The chance (per tick) that the entity eats. Settings this to N would mean there is a 1 in N chance.
*/
public EatBlockGoal(
@NotNull EntityCreature entityCreature,
@NotNull Short2ShortArrayMap eatInMap,
@NotNull Short2ShortArrayMap eatBelowMap,
int chancePerTick) {
super(entityCreature);
this.eatInMap = eatInMap;
this.eatBelowMap = eatBelowMap;
this.chancePerTick = chancePerTick;
}
@Override
public boolean shouldStart() {
// TODO: is Baby
if (RANDOM.nextInt(chancePerTick) != 0) {
return false;
}
final Instance instance = entityCreature.getInstance();
// An entity shouldn't be eating blocks on null instances.
if (instance == null) {
return false;
}
final BlockPosition blockPosition = entityCreature.getPosition().toBlockPosition();
final short blockStateIdIn = instance.getBlock(blockPosition.clone().subtract(0, 1, 0)).stateId();
final short blockStateIdBelow = instance.getBlock(blockPosition.clone().subtract(0, 2, 0)).stateId();
return eatInMap.containsKey(blockStateIdIn) || eatBelowMap.containsKey(blockStateIdBelow);
}
@Override
public void start() {
this.eatAnimationTick = 40;
// TODO: EatBlockEvent call here.
// Stop moving
entityCreature.getNavigator().setPathTo(null);
}
@Override
public void tick(long time) {
this.eatAnimationTick = Math.max(0, this.eatAnimationTick - 1);
if (this.eatAnimationTick != 4) {
return;
}
Instance instance = entityCreature.getInstance();
final BlockPosition currentPosition = entityCreature.getPosition().toBlockPosition().clone().subtract(0, 1, 0);
final BlockPosition belowPosition = currentPosition.clone().subtract(0, 1, 0);
final short blockStateIdIn = instance.getBlock(currentPosition).stateId();
final short blockStateIdBelow = instance.getBlock(belowPosition).stateId();
if (eatInMap.containsKey(blockStateIdIn)) {
instance.setBlock(currentPosition, Block.fromStateId(eatInMap.get(blockStateIdIn)));
} else if (eatBelowMap.containsKey(blockStateIdBelow)) {
instance.setBlock(belowPosition, Block.fromStateId(eatBelowMap.get(blockStateIdBelow)));
}
// TODO: Call Entity Eat Animation
}
@Override
public boolean shouldEnd() {
return eatAnimationTick <= 0;
}
@Override
public void end() {
this.eatAnimationTick = 0;
}
}

View File

@ -4,8 +4,7 @@ import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.entity.pathfinding.Navigator;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
@ -15,14 +14,13 @@ public class FollowTargetGoal extends GoalSelector {
private final Duration pathDuration;
private long lastUpdateTime = 0;
private boolean forceEnd = false;
private Position lastTargetPos;
private Point lastTargetPos;
/**
* Creates a follow target goal object.
*
* @param entityCreature the entity
* @param pathUpdateOption the time between each path update (to check if the target moved)
*
* @deprecated Replaced by {@link #FollowTargetGoal(EntityCreature, Duration)}
*/
@SuppressWarnings("removal")
@ -34,8 +32,8 @@ public class FollowTargetGoal extends GoalSelector {
/**
* Creates a follow target goal object.
*
* @param entityCreature the entity
* @param pathDuration the time between each path update (to check if the target moved)
* @param entityCreature the entity
* @param pathDuration the time between each path update (to check if the target moved)
*/
public FollowTargetGoal(@NotNull EntityCreature entityCreature, @NotNull Duration pathDuration) {
super(entityCreature);
@ -45,7 +43,7 @@ public class FollowTargetGoal extends GoalSelector {
@Override
public boolean shouldStart() {
return entityCreature.getTarget() != null &&
getDistance(entityCreature.getTarget().getPosition(), entityCreature.getPosition()) >= 2;
entityCreature.getTarget().getPosition().distance(entityCreature.getPosition()) >= 2;
}
@Override
@ -54,19 +52,18 @@ public class FollowTargetGoal extends GoalSelector {
forceEnd = false;
lastTargetPos = null;
final Entity target = entityCreature.getTarget();
if (target != null) {
Navigator navigator = entityCreature.getNavigator();
lastTargetPos = target.getPosition().clone();
if (getDistance(lastTargetPos, entityCreature.getPosition()) < 2) {
lastTargetPos = target.getPosition();
if (lastTargetPos.distance(entityCreature.getPosition()) < 2) {
forceEnd = true;
navigator.setPathTo(null);
return;
}
if (navigator.getPathPosition() == null ||
(!navigator.getPathPosition().isSimilar(lastTargetPos))) {
(!navigator.getPathPosition().samePoint(lastTargetPos))) {
navigator.setPathTo(lastTargetPos);
} else {
forceEnd = true;
@ -83,28 +80,24 @@ public class FollowTargetGoal extends GoalSelector {
pathDuration.toMillis() + lastUpdateTime > time) {
return;
}
Position targetPos = entityCreature.getTarget() != null ? entityCreature.getTarget().getPosition() : null;
if (targetPos != null && !targetPos.equals(lastTargetPos)) {
lastUpdateTime = time;
lastTargetPos.copy(lastTargetPos);
entityCreature.getNavigator().setPathTo(targetPos);
final var targetPos = entityCreature.getTarget() != null ? entityCreature.getTarget().getPosition() : null;
if (targetPos != null && !targetPos.samePoint(lastTargetPos)) {
this.lastUpdateTime = time;
this.lastTargetPos = targetPos;
this.entityCreature.getNavigator().setPathTo(targetPos);
}
}
@Override
public boolean shouldEnd() {
final Entity target = entityCreature.getTarget();
return forceEnd ||
entityCreature.getTarget() == null ||
getDistance(entityCreature.getTarget().getPosition(), entityCreature.getPosition()) < 2;
target == null ||
target.getPosition().distance(entityCreature.getPosition()) < 2;
}
@Override
public void end() {
entityCreature.getNavigator().setPathTo(null);
}
private double getDistance(@NotNull Position a, @NotNull Position b) {
return MathUtils.square(a.getX() - b.getX()) +
MathUtils.square(a.getZ() - b.getZ());
}
}

View File

@ -5,7 +5,7 @@ import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.entity.ai.TargetSelector;
import net.minestom.server.entity.pathfinding.Navigator;
import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull;
@ -61,7 +61,7 @@ public class MeleeAttackGoal extends GoalSelector {
@Override
public void start() {
final Position targetPosition = this.cachedTarget.getPosition();
final Point targetPosition = this.cachedTarget.getPosition();
entityCreature.getNavigator().setPathTo(targetPosition);
}
@ -90,9 +90,9 @@ public class MeleeAttackGoal extends GoalSelector {
// Move toward the target entity
Navigator navigator = entityCreature.getNavigator();
final Position pathPosition = navigator.getPathPosition();
final Position targetPosition = target.getPosition();
if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) {
final var pathPosition = navigator.getPathPosition();
final var targetPosition = target.getPosition();
if (pathPosition == null || !pathPosition.samePoint(targetPosition)) {
if (this.cooldown.isReady(time)) {
this.cooldown.refreshLastUpdate(time);
navigator.setPathTo(targetPosition);

View File

@ -2,7 +2,7 @@ package net.minestom.server.entity.ai.goal;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.utils.Vector;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
@ -13,20 +13,20 @@ public class RandomLookAroundGoal extends GoalSelector {
private static final Random RANDOM = new Random();
private final int chancePerTick;
private final Supplier<Integer> minimalLookTimeSupplier;
private final Function<EntityCreature, Vector> randomDirectionFunction;
private Vector lookDirection;
private final Function<EntityCreature, Vec> randomDirectionFunction;
private Vec lookDirection;
private int lookTime = 0;
public RandomLookAroundGoal(EntityCreature entityCreature, int chancePerTick) {
this(entityCreature, chancePerTick,
// These two functions act similarily enough to how MC randomly looks around.
// These two functions act similarly enough to how MC randomly looks around.
// Look in one direction for at most 40 ticks and at minimum 20 ticks.
() -> 20 + RANDOM.nextInt(20),
// Look at a random block
(creature) -> {
final double n = Math.PI * 2 * RANDOM.nextDouble();
return new Vector(
return new Vec(
(float) Math.cos(n),
0,
(float) Math.sin(n)
@ -44,8 +44,7 @@ public class RandomLookAroundGoal extends GoalSelector {
EntityCreature entityCreature,
int chancePerTick,
@NotNull Supplier<Integer> minimalLookTimeSupplier,
@NotNull Function<EntityCreature, Vector> randomDirectionFunction
) {
@NotNull Function<EntityCreature, Vec> randomDirectionFunction) {
super(entityCreature);
this.chancePerTick = chancePerTick;
this.minimalLookTimeSupplier = minimalLookTimeSupplier;
@ -69,7 +68,7 @@ public class RandomLookAroundGoal extends GoalSelector {
@Override
public void tick(long time) {
--lookTime;
entityCreature.setView(entityCreature.getPosition().clone().setDirection(lookDirection));
entityCreature.refreshPosition(entityCreature.getPosition().withDirection(lookDirection));
}
@Override
@ -79,6 +78,5 @@ public class RandomLookAroundGoal extends GoalSelector {
@Override
public void end() {
}
}

View File

@ -2,7 +2,7 @@ package net.minestom.server.entity.ai.goal;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@ -14,14 +14,13 @@ public class RandomStrollGoal extends GoalSelector {
private static final long DELAY = 2500;
private final int radius;
private final List<Position> closePositions;
private final List<Vec> closePositions;
private long lastStroll;
public RandomStrollGoal(@NotNull EntityCreature entityCreature, int radius) {
super(entityCreature);
this.radius = radius;
this.closePositions = getNearbyBlocks(radius);
}
@ -33,20 +32,17 @@ public class RandomStrollGoal extends GoalSelector {
@Override
public void start() {
Collections.shuffle(closePositions);
for (Position position : closePositions) {
final Position target = position.clone().add(entityCreature.getPosition());
for (var position : closePositions) {
final var target = entityCreature.getPosition().add(position);
final boolean result = entityCreature.getNavigator().setPathTo(target);
if (result) {
break;
}
}
}
@Override
public void tick(long time) {
}
@Override
@ -64,17 +60,15 @@ public class RandomStrollGoal extends GoalSelector {
}
@NotNull
private List<Position> getNearbyBlocks(int radius) {
List<Position> blocks = new ArrayList<>();
private List<Vec> getNearbyBlocks(int radius) {
List<Vec> blocks = new ArrayList<>();
for (int x = -radius; x <= radius; x++) {
for (int y = -radius; y <= radius; y++) {
for (int z = -radius; z <= radius; z++) {
final Position position = new Position(x, y, z);
blocks.add(position);
blocks.add(new Vec(x, y, z));
}
}
}
return blocks;
}
}

View File

@ -104,7 +104,7 @@ public class RangedAttackGoal extends GoalSelector {
if (distanceSquared <= this.attackRangeSquared) {
if (!Cooldown.hasCooldown(time, this.lastShot, this.delay)) {
if (this.entityCreature.hasLineOfSight(target)) {
Position to = target.getPosition().clone().add(0D, target.getEyeHeight(), 0D);
final var to = target.getPosition().add(0D, target.getEyeHeight(), 0D);
Function<Entity, EntityProjectile> projectileGenerator = this.projectileGenerator;
if (projectileGenerator == null) {
@ -121,15 +121,15 @@ public class RangedAttackGoal extends GoalSelector {
}
}
Navigator navigator = this.entityCreature.getNavigator();
Position pathPosition = navigator.getPathPosition();
final var pathPosition = navigator.getPathPosition();
if (!comeClose && distanceSquared <= this.desirableRangeSquared) {
if (pathPosition != null) {
navigator.setPathTo(null);
}
return;
}
Position targetPosition = target.getPosition();
if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) {
final var targetPosition = target.getPosition();
if (pathPosition == null || !pathPosition.samePoint(targetPosition)) {
if (this.cooldown.isReady(time)) {
this.cooldown.refreshLastUpdate(time);
navigator.setPathTo(targetPosition);

View File

@ -1,5 +1,6 @@
package net.minestom.server.entity.fakeplayer;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.block.BlockFace;
@ -13,7 +14,6 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.play.KeepAlivePacket;
import net.minestom.server.network.packet.server.play.PlayerPositionAndLookPacket;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import net.minestom.server.utils.validate.Check;
@ -179,7 +179,7 @@ public class FakePlayerController {
* @param blockPosition The position of the block to be excavated.
* @param blockFace From where the block is struck.
*/
public void startDigging(BlockPosition blockPosition, BlockFace blockFace) {
public void startDigging(Point blockPosition, BlockFace blockFace) {
ClientPlayerDiggingPacket playerDiggingPacket = new ClientPlayerDiggingPacket();
playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.STARTED_DIGGING;
playerDiggingPacket.blockPosition = blockPosition;
@ -193,7 +193,7 @@ public class FakePlayerController {
* @param blockPosition The position of the block to be excavated.
* @param blockFace From where the block is struck.
*/
public void stopDigging(BlockPosition blockPosition, BlockFace blockFace) {
public void stopDigging(Point blockPosition, BlockFace blockFace) {
ClientPlayerDiggingPacket playerDiggingPacket = new ClientPlayerDiggingPacket();
playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING;
playerDiggingPacket.blockPosition = blockPosition;
@ -207,7 +207,7 @@ public class FakePlayerController {
* @param blockPosition The position of the block to be excavated.
* @param blockFace From where the block is struck.
*/
public void finishDigging(BlockPosition blockPosition, BlockFace blockFace) {
public void finishDigging(Point blockPosition, BlockFace blockFace) {
ClientPlayerDiggingPacket playerDiggingPacket = new ClientPlayerDiggingPacket();
playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.FINISHED_DIGGING;
playerDiggingPacket.blockPosition = blockPosition;

View File

@ -8,7 +8,7 @@ import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.metadata.other.ArmorStandMeta;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
@ -25,7 +25,7 @@ public class Hologram implements Viewable {
private final Entity entity;
private final float yOffset;
private Position position;
private Pos position;
private Component text;
private boolean removed;
@ -36,35 +36,8 @@ public class Hologram implements Viewable {
* @param instance The instance where the hologram should be spawned.
* @param spawnPosition The spawn position of this hologram.
* @param text The text of this hologram.
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
* @deprecated Use {@link #Hologram(Instance, Position, Component, boolean)}
*/
@Deprecated
public Hologram(Instance instance, Position spawnPosition, JsonMessage text, boolean autoViewable) {
this(instance, spawnPosition, text.asComponent(), autoViewable);
}
/**
* Constructs a new {@link Hologram} with the given parameters.
*
* @param instance The instance where the hologram should be spawned.
* @param spawnPosition The spawn position of this hologram.
* @param text The text of this hologram.
* @deprecated Use {@link #Hologram(Instance, Position, Component)}
*/
@Deprecated
public Hologram(Instance instance, Position spawnPosition, JsonMessage text) {
this(instance, spawnPosition, text, true);
}
/**
* Constructs a new {@link Hologram} with the given parameters.
*
* @param instance The instance where the hologram should be spawned.
* @param spawnPosition The spawn position of this hologram.
* @param text The text of this hologram.
*/
public Hologram(Instance instance, Position spawnPosition, Component text) {
public Hologram(Instance instance, Pos spawnPosition, Component text) {
this(instance, spawnPosition, text, true);
}
@ -76,7 +49,7 @@ public class Hologram implements Viewable {
* @param text The text of this hologram.
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
*/
public Hologram(Instance instance, Position spawnPosition, Component text, boolean autoViewable) {
public Hologram(Instance instance, Pos spawnPosition, Component text, boolean autoViewable) {
this(instance, spawnPosition, text, autoViewable, false);
}
@ -88,7 +61,7 @@ public class Hologram implements Viewable {
* @param text The text of this hologram.
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
*/
public Hologram(Instance instance, Position spawnPosition, Component text, boolean autoViewable, boolean marker) {
public Hologram(Instance instance, Pos spawnPosition, Component text, boolean autoViewable, boolean marker) {
this.entity = new Entity(EntityType.ARMOR_STAND);
ArmorStandMeta armorStandMeta = (ArmorStandMeta) entity.getEntityMeta();
@ -109,7 +82,7 @@ public class Hologram implements Viewable {
armorStandMeta.setNotifyAboutChanges(true);
this.entity.setInstance(instance, spawnPosition.clone().add(0, this.yOffset, 0));
this.entity.setInstance(instance, spawnPosition.add(0, this.yOffset, 0));
this.entity.setAutoViewable(autoViewable);
this.position = spawnPosition;
@ -121,7 +94,7 @@ public class Hologram implements Viewable {
*
* @return the hologram's position
*/
public Position getPosition() {
public Pos getPosition() {
return position;
}
@ -130,11 +103,10 @@ public class Hologram implements Viewable {
*
* @param position the new hologram's position
*/
public void setPosition(Position position) {
public void setPosition(Pos position) {
checkRemoved();
position.add(0, this.yOffset, 0);
this.position = position;
this.entity.teleport(position);
this.position = position.add(0, this.yOffset, 0);
this.entity.teleport(this.position);
}
/**

View File

@ -1,9 +1,9 @@
package net.minestom.server.entity.metadata;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.Player;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -85,11 +85,11 @@ public class LivingEntityMeta extends EntityMeta {
}
@Nullable
public BlockPosition getBedInWhichSleepingPosition() {
public Point getBedInWhichSleepingPosition() {
return super.metadata.getIndex(OFFSET + 6, null);
}
public void setBedInWhichSleepingPosition(@Nullable BlockPosition value) {
public void setBedInWhichSleepingPosition(@Nullable Point value) {
super.metadata.setIndex(OFFSET + 6, Metadata.OptPosition(value));
}

View File

@ -1,8 +1,9 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
public class TurtleMeta extends AnimalMeta {
@ -13,12 +14,11 @@ public class TurtleMeta extends AnimalMeta {
super(entity, metadata);
}
@NotNull
public BlockPosition getHomePosition() {
return super.metadata.getIndex(OFFSET, new BlockPosition(0, 0, 0));
public @NotNull Point getHomePosition() {
return super.metadata.getIndex(OFFSET, Vec.ZERO);
}
public void setBlockPosition(@NotNull BlockPosition value) {
public void setBlockPosition(@NotNull Point value) {
super.metadata.setIndex(OFFSET, Metadata.Position(value));
}
@ -38,12 +38,11 @@ public class TurtleMeta extends AnimalMeta {
super.metadata.setIndex(OFFSET + 2, Metadata.Boolean(value));
}
@NotNull
public BlockPosition getTravelPosition() {
return super.metadata.getIndex(OFFSET + 3, new BlockPosition(0, 0, 0));
public @NotNull Point getTravelPosition() {
return super.metadata.getIndex(OFFSET + 3, Vec.ZERO);
}
public void setTravelPosition(@NotNull BlockPosition value) {
public void setTravelPosition(@NotNull Point value) {
super.metadata.setIndex(OFFSET + 3, Metadata.Position(value));
}

View File

@ -1,8 +1,8 @@
package net.minestom.server.entity.metadata.golem;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Direction;
import org.jetbrains.annotations.NotNull;
@ -22,11 +22,11 @@ public class ShulkerMeta extends AbstractGolemMeta {
super.metadata.setIndex(OFFSET, Metadata.Direction(value));
}
public BlockPosition getAttachmentPosition() {
public Point getAttachmentPosition() {
return super.metadata.getIndex(OFFSET + 1, null);
}
public void setAttachmentPosition(BlockPosition value) {
public void setAttachmentPosition(Point value) {
super.metadata.setIndex(OFFSET + 1, Metadata.OptPosition(value));
}

View File

@ -1,10 +1,9 @@
package net.minestom.server.entity.metadata.other;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.entity.metadata.LivingEntityMeta;
import net.minestom.server.utils.Vector;
import org.jetbrains.annotations.NotNull;
public class ArmorStandMeta extends LivingEntityMeta {
@ -53,56 +52,56 @@ public class ArmorStandMeta extends LivingEntityMeta {
}
@NotNull
public Vector getHeadRotation() {
return super.metadata.getIndex(OFFSET + 1, new Vector(0D, 0D, 0D));
public Vec getHeadRotation() {
return super.metadata.getIndex(OFFSET + 1, Vec.ZERO);
}
public void setHeadRotation(@NotNull Vector value) {
public void setHeadRotation(@NotNull Vec value) {
super.metadata.setIndex(OFFSET + 1, Metadata.Rotation(value));
}
@NotNull
public Vector getBodyRotation() {
return super.metadata.getIndex(OFFSET + 2, new Vector(0D, 0D, 0D));
public Vec getBodyRotation() {
return super.metadata.getIndex(OFFSET + 2, Vec.ZERO);
}
public void setBodyRotation(@NotNull Vector value) {
public void setBodyRotation(@NotNull Vec value) {
super.metadata.setIndex(OFFSET + 2, Metadata.Rotation(value));
}
@NotNull
public Vector getLeftArmRotation() {
return super.metadata.getIndex(OFFSET + 3, new Vector(-10D, 0D, -10D));
public Vec getLeftArmRotation() {
return super.metadata.getIndex(OFFSET + 3, new Vec(-10D, 0D, -10D));
}
public void setLeftArmRotation(@NotNull Vector value) {
public void setLeftArmRotation(@NotNull Vec value) {
super.metadata.setIndex(OFFSET + 3, Metadata.Rotation(value));
}
@NotNull
public Vector getRightArmRotation() {
return super.metadata.getIndex(OFFSET + 4, new Vector(-15D, 0D, 10D));
public Vec getRightArmRotation() {
return super.metadata.getIndex(OFFSET + 4, new Vec(-15D, 0D, 10D));
}
public void setRightArmRotation(@NotNull Vector value) {
public void setRightArmRotation(@NotNull Vec value) {
super.metadata.setIndex(OFFSET + 4, Metadata.Rotation(value));
}
@NotNull
public Vector getLeftLegRotation() {
return super.metadata.getIndex(OFFSET + 5, new Vector(-1D, 0D, -1D));
public Vec getLeftLegRotation() {
return super.metadata.getIndex(OFFSET + 5, new Vec(-1D, 0D, -1D));
}
public void setLeftLegRotation(@NotNull Vector value) {
public void setLeftLegRotation(@NotNull Vec value) {
super.metadata.setIndex(OFFSET + 5, Metadata.Rotation(value));
}
@NotNull
public Vector getRightLegRotation() {
return super.metadata.getIndex(OFFSET + 6, new Vector(1D, 0D, 1D));
public Vec getRightLegRotation() {
return super.metadata.getIndex(OFFSET + 6, new Vec(1D, 0D, 1D));
}
public void setRightLegRotation(@NotNull Vector value) {
public void setRightLegRotation(@NotNull Vec value) {
super.metadata.setIndex(OFFSET + 6, Metadata.Rotation(value));
}

View File

@ -1,9 +1,9 @@
package net.minestom.server.entity.metadata.other;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -15,12 +15,11 @@ public class EndCrystalMeta extends EntityMeta {
super(entity, metadata);
}
@Nullable
public BlockPosition getBeamTarget() {
public @Nullable Point getBeamTarget() {
return super.metadata.getIndex(OFFSET, null);
}
public void setBeamTarget(@Nullable BlockPosition value) {
public void setBeamTarget(@Nullable Point value) {
super.metadata.setIndex(OFFSET, Metadata.OptPosition(value));
}

View File

@ -1,11 +1,12 @@
package net.minestom.server.entity.metadata.other;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.entity.metadata.ObjectDataProvider;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
public class FallingBlockMeta extends EntityMeta implements ObjectDataProvider {
@ -18,11 +19,11 @@ public class FallingBlockMeta extends EntityMeta implements ObjectDataProvider {
super(entity, metadata);
}
public BlockPosition getSpawnPosition() {
return super.metadata.getIndex(OFFSET, new BlockPosition(0, 0, 0));
public Point getSpawnPosition() {
return super.metadata.getIndex(OFFSET, Vec.ZERO);
}
public void setSpawnPosition(BlockPosition value) {
public void setSpawnPosition(Point value) {
super.metadata.setIndex(OFFSET, Metadata.Position(value));
}

View File

@ -1,9 +1,9 @@
package net.minestom.server.entity.metadata.water;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
public class DolphinMeta extends WaterAnimalMeta {
@ -15,11 +15,11 @@ public class DolphinMeta extends WaterAnimalMeta {
}
@NotNull
public BlockPosition getTreasurePosition() {
return super.metadata.getIndex(OFFSET, new BlockPosition(0, 0, 0));
public Point getTreasurePosition() {
return super.metadata.getIndex(OFFSET, Vec.ZERO);
}
public void setTreasurePosition(@NotNull BlockPosition value) {
public void setTreasurePosition(@NotNull Point value) {
super.metadata.setIndex(OFFSET, Metadata.Position(value));
}

View File

@ -4,13 +4,14 @@ import com.extollit.gaming.ai.path.HydrazinePathFinder;
import com.extollit.gaming.ai.path.PathOptions;
import com.extollit.gaming.ai.path.model.IPath;
import net.minestom.server.collision.CollisionUtils;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.WorldBorder;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.position.PositionUtils;
import org.jetbrains.annotations.NotNull;
@ -26,7 +27,7 @@ public class Navigator {
private final PFPathingEntity pathingEntity;
private HydrazinePathFinder pathFinder;
private IPath path;
private Position pathPosition;
private Point pathPosition;
private final Entity entity;
@ -43,17 +44,16 @@ public class Navigator {
* @param direction the targeted position
* @param speed define how far the entity will move
*/
public void moveTowards(@NotNull Position direction, double speed) {
public void moveTowards(@NotNull Point direction, double speed) {
final Pos position = entity.getPosition();
final Position position = entity.getPosition();
final double currentX = position.x();
final double currentY = position.y();
final double currentZ = position.z();
final double currentX = position.getX();
final double currentY = position.getY();
final double currentZ = position.getZ();
final double targetX = direction.getX();
final double targetY = direction.getY();
final double targetZ = direction.getZ();
final double targetX = direction.x();
final double targetY = direction.y();
final double targetZ = direction.z();
final double dx = targetX - currentX;
final double dy = targetY - currentY;
@ -71,24 +71,17 @@ public class Navigator {
final double speedZ = Math.sin(radians) * speed;
// Update 'position' view
PositionUtils.lookAlong(position, dx, direction.getY(), dz);
Position newPosition = new Position();
Vector newVelocityOut = new Vector();
final var view = PositionUtils.lookAlong(position, dx, direction.y(), dz);
entity.setView(view.yaw(), view.pitch());
// Prevent ghosting
CollisionUtils.handlePhysics(entity,
new Vector(speedX, speedY, speedZ),
newPosition, newVelocityOut);
// Will move the entity during Entity#tick
position.copyCoordinates(newPosition);
final var physicsResult = CollisionUtils.handlePhysics(entity, new Vec(speedX, speedY, speedZ));
entity.refreshPosition(physicsResult.newPosition());
}
public void jump(float height) {
// FIXME magic value
final Vector velocity = new Vector(0, height * 2.5f, 0);
this.entity.setVelocity(velocity);
this.entity.setVelocity(new Vec(0, height * 2.5f, 0));
}
/**
@ -99,13 +92,13 @@ public class Navigator {
* The position is cloned, if you want the entity to continually follow this position object
* you need to call this when you want the path to update.
*
* @param position the position to find the path to, null to reset the pathfinder
* @param point the position to find the path to, null to reset the pathfinder
* @param bestEffort whether to use the best-effort algorithm to the destination,
* if false then this method is more likely to return immediately
* @return true if a path has been found
*/
public synchronized boolean setPathTo(@Nullable Position position, boolean bestEffort) {
if (position != null && pathPosition != null && position.isSimilar(pathPosition)) {
public synchronized boolean setPathTo(@Nullable Point point, boolean bestEffort) {
if (point != null && pathPosition != null && point.samePoint(pathPosition)) {
// Tried to set path to the same target position
return false;
}
@ -118,7 +111,7 @@ public class Navigator {
}
pathFinder.reset();
if (position == null) {
if (point == null) {
return false;
}
@ -129,38 +122,36 @@ public class Navigator {
// Can't path outside of the world border
final WorldBorder worldBorder = instance.getWorldBorder();
if (!worldBorder.isInside(position)) {
if (!worldBorder.isInside(point)) {
return false;
}
// Can't path in an unloaded chunk
final Chunk chunk = instance.getChunkAt(position);
final Chunk chunk = instance.getChunkAt(point);
if (!ChunkUtils.isLoaded(chunk)) {
return false;
}
final Position targetPosition = position.clone();
final PathOptions pathOptions = new PathOptions()
.targetingStrategy(bestEffort ? PathOptions.TargetingStrategy.gravitySnap :
PathOptions.TargetingStrategy.none);
final IPath path = pathFinder.initiatePathTo(
targetPosition.getX(),
targetPosition.getY(),
targetPosition.getZ(),
point.x(),
point.y(),
point.z(),
pathOptions);
this.path = path;
final boolean success = path != null;
this.pathPosition = success ? targetPosition : null;
this.pathPosition = success ? point : null;
return success;
}
/**
* @see #setPathTo(Position, boolean) with {@code bestEffort} sets to {@code true}.
* @see #setPathTo(Point, boolean) with {@code bestEffort} sets to {@code true}.
*/
public boolean setPathTo(@Nullable Position position) {
public boolean setPathTo(@Nullable Point position) {
return setPathTo(position, true);
}
@ -174,7 +165,7 @@ public class Navigator {
this.path = path;
if (path != null) {
final Position targetPosition = pathingEntity.getTargetPosition();
final Point targetPosition = pathingEntity.getTargetPosition();
if (targetPosition != null) {
moveTowards(targetPosition, speed);
}
@ -220,8 +211,7 @@ public class Navigator {
*
* @return the target pathfinder position, null if there is no one
*/
@Nullable
public Position getPathPosition() {
public @Nullable Point getPathPosition() {
return pathPosition;
}
@ -229,10 +219,10 @@ public class Navigator {
* Changes the position this element is trying to reach.
*
* @param pathPosition the new current path position
* @deprecated Please use {@link #setPathTo(Position)}
* @deprecated Please use {@link #setPathTo(Point)}
*/
@Deprecated
public void setPathPosition(@Nullable Position pathPosition) {
public void setPathPosition(@Nullable Point pathPosition) {
this.pathPosition = pathPosition;
}

View File

@ -5,9 +5,10 @@ import com.extollit.gaming.ai.path.model.IPathingEntity;
import com.extollit.gaming.ai.path.model.Passibility;
import com.extollit.linalg.immutable.Vec3d;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
public class PFPathingEntity implements IPathingEntity {
@ -16,7 +17,7 @@ public class PFPathingEntity implements IPathingEntity {
private final Entity entity;
private float searchRange;
private Position targetPosition;
private Point targetPosition;
// Capacities
private boolean fireResistant;
@ -36,7 +37,7 @@ public class PFPathingEntity implements IPathingEntity {
this.searchRange = getAttributeValue(Attribute.FOLLOW_RANGE);
}
public Position getTargetPosition() {
public Point getTargetPosition() {
return targetPosition;
}
@ -193,18 +194,17 @@ public class PFPathingEntity implements IPathingEntity {
@Override
public void moveTo(Vec3d position, Passibility passibility, Gravitation gravitation) {
this.targetPosition = new Position(position.x, position.y, position.z);
final double entityY = entity.getPosition().getY();
if (entityY < targetPosition.getY()) {
this.targetPosition = new Vec(position.x, position.y, position.z);
final double entityY = entity.getPosition().y();
if (entityY < targetPosition.y()) {
this.navigator.jump(1);
}
}
@Override
public Vec3d coordinates() {
final Position position = entity.getPosition();
return new Vec3d(position.getX(), position.getY(), position.getZ());
final var position = entity.getPosition();
return new Vec3d(position.x(), position.y(), position.z());
}
@Override

View File

@ -5,22 +5,23 @@ import net.minestom.server.entity.EntityProjectile;
import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
/**
* Called with {@link EntityProjectile#shoot(Position, double, double)}
* Called with {@link EntityProjectile#shoot(Point, double, double)}
*/
public class EntityShootEvent implements EntityEvent, CancellableEvent {
private final Entity entity;
private final Entity projectile;
private final Position to;
private final Point to;
private double power;
private double spread;
private boolean cancelled;
public EntityShootEvent(@NotNull Entity entity, @NotNull Entity projectile, @NotNull Position to, double power, double spread) {
public EntityShootEvent(@NotNull Entity entity, @NotNull Entity projectile, @NotNull Point to, double power, double spread) {
this.entity = entity;
this.projectile = projectile;
this.to = to;
@ -42,7 +43,7 @@ public class EntityShootEvent implements EntityEvent, CancellableEvent {
*
* @return the position projectile was shot to.
*/
public Position getTo() {
public Point getTo() {
return this.to;
}

View File

@ -3,20 +3,20 @@ package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.utils.Vector;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
/**
* Called when a velocity is applied to an entity using {@link Entity#setVelocity(Vector)}.
* Called when a velocity is applied to an entity using {@link Entity#setVelocity(Vec)}.
*/
public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
private final Entity entity;
private Vector velocity;
private Vec velocity;
private boolean cancelled;
public EntityVelocityEvent(@NotNull Entity entity, @NotNull Vector velocity) {
public EntityVelocityEvent(@NotNull Entity entity, @NotNull Vec velocity) {
this.entity = entity;
this.velocity = velocity;
}
@ -26,9 +26,8 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
*
* @return the entity
*/
@NotNull
@Override
public Entity getEntity() {
public @NotNull Entity getEntity() {
return entity;
}
@ -37,8 +36,7 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
*
* @return the velocity
*/
@NotNull
public Vector getVelocity() {
public @NotNull Vec getVelocity() {
return velocity;
}
@ -47,7 +45,7 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
*
* @param velocity the new velocity
*/
public void setVelocity(@NotNull Vector velocity) {
public void setVelocity(@NotNull Vec velocity) {
this.velocity = velocity;
}

View File

@ -5,7 +5,7 @@ import net.minestom.server.event.trait.BlockEvent;
import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
public class PlayerBlockBreakEvent implements PlayerEvent, BlockEvent, CancellableEvent {

View File

@ -6,8 +6,7 @@ import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
/**

View File

@ -5,8 +5,7 @@ import net.minestom.server.event.trait.BlockEvent;
import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
/**

View File

@ -3,7 +3,7 @@ package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
/**
@ -12,11 +12,11 @@ import org.jetbrains.annotations.NotNull;
public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
private final Player player;
private Position newPosition;
private Pos newPosition;
private boolean cancelled;
public PlayerMoveEvent(@NotNull Player player, @NotNull Position newPosition) {
public PlayerMoveEvent(@NotNull Player player, @NotNull Pos newPosition) {
this.player = player;
this.newPosition = newPosition;
}
@ -26,8 +26,7 @@ public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
*
* @return the new position
*/
@NotNull
public Position getNewPosition() {
public @NotNull Pos getNewPosition() {
return newPosition;
}
@ -36,7 +35,7 @@ public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
*
* @param newPosition the new target position
*/
public void setNewPosition(@NotNull Position newPosition) {
public void setNewPosition(@NotNull Pos newPosition) {
this.newPosition = newPosition;
}

View File

@ -1,9 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
import net.minestom.server.event.Event;
import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
/**
@ -13,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
public class PlayerRespawnEvent implements PlayerEvent {
private final Player player;
private Position respawnPosition;
private Pos respawnPosition;
public PlayerRespawnEvent(@NotNull Player player) {
this.player = player;
@ -27,8 +26,7 @@ public class PlayerRespawnEvent implements PlayerEvent {
*
* @return the respawn position
*/
@NotNull
public Position getRespawnPosition() {
public @NotNull Pos getRespawnPosition() {
return respawnPosition;
}
@ -37,7 +35,7 @@ public class PlayerRespawnEvent implements PlayerEvent {
*
* @param respawnPosition the new respawn position
*/
public void setRespawnPosition(@NotNull Position respawnPosition) {
public void setRespawnPosition(@NotNull Pos respawnPosition) {
this.respawnPosition = respawnPosition;
}

View File

@ -5,7 +5,7 @@ import net.minestom.server.event.trait.BlockEvent;
import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
/**

View File

@ -5,7 +5,7 @@ import net.minestom.server.event.trait.ItemEvent;
import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.Direction;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
/**

View File

@ -2,6 +2,8 @@ package net.minestom.server.instance;
import net.minestom.server.Tickable;
import net.minestom.server.Viewable;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.Player;
@ -15,10 +17,9 @@ import net.minestom.server.instance.block.BlockSetter;
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
import net.minestom.server.network.packet.server.play.UpdateLightPacket;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.ArrayUtils;
import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagHandler;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.ArrayUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkSupplier;
import net.minestom.server.world.biomes.Biome;
@ -208,13 +209,12 @@ public abstract class Chunk implements BlockGetter, BlockSetter, Viewable, Ticka
}
/**
* Creates a {@link Position} object based on this chunk.
* Gets the world position of this chunk.
*
* @return the position of this chunk
*/
@NotNull
public Position toPosition() {
return new Position(CHUNK_SIZE_Z * getChunkX(), 0, CHUNK_SIZE_Z * getChunkZ());
public @NotNull Point toPosition() {
return new Vec(CHUNK_SIZE_Z * getChunkX(), 0, CHUNK_SIZE_Z * getChunkZ());
}
/**

View File

@ -2,14 +2,12 @@ package net.minestom.server.instance;
import com.extollit.gaming.ai.path.model.ColumnarOcclusionFieldList;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.pathfinding.PFBlock;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.validate.Check;
import net.minestom.server.world.biomes.Biome;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -17,7 +15,6 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.lang.ref.SoftReference;
import java.util.Map;
import java.time.Duration;
import java.util.Set;
import java.util.TreeMap;
@ -99,7 +96,7 @@ public class DynamicChunk extends Chunk {
final int x = ChunkUtils.blockIndexToChunkPositionX(index);
final int y = ChunkUtils.blockIndexToChunkPositionY(index);
final int z = ChunkUtils.blockIndexToChunkPositionZ(index);
final BlockPosition blockPosition = new BlockPosition(x, y, z);
final Vec blockPosition = new Vec(x, y, z);
final Block block = getBlock(blockPosition);
entry.getValue().tick(new BlockHandler.Tick(block, instance, blockPosition));

View File

@ -1,8 +1,8 @@
package net.minestom.server.instance;
import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.packet.server.play.ExplosionPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.PacketUtils;
import org.jetbrains.annotations.NotNull;
@ -48,7 +48,7 @@ public abstract class Explosion {
* @param instance instance to perform this explosion in
* @return list of blocks that will be broken.
*/
protected abstract List<BlockPosition> prepare(Instance instance);
protected abstract List<Point> prepare(Instance instance);
/**
* Performs the explosion and send the corresponding packet
@ -56,7 +56,7 @@ public abstract class Explosion {
* @param instance instance to perform this explosion in
*/
public void apply(@NotNull Instance instance) {
List<BlockPosition> blocks = prepare(instance);
List<Point> blocks = prepare(instance);
ExplosionPacket packet = new ExplosionPacket();
packet.x = getCenterX();
packet.y = getCenterY();
@ -68,11 +68,11 @@ public abstract class Explosion {
packet.records = new byte[3 * blocks.size()];
for (int i = 0; i < blocks.size(); i++) {
final BlockPosition pos = blocks.get(i);
final var pos = blocks.get(i);
instance.setBlock(pos, Block.AIR);
final byte x = (byte) (pos.getX() - Math.floor(getCenterX()));
final byte y = (byte) (pos.getY() - Math.floor(getCenterY()));
final byte z = (byte) (pos.getZ() - Math.floor(getCenterZ()));
final byte x = (byte) (pos.x() - Math.floor(getCenterX()));
final byte y = (byte) (pos.y() - Math.floor(getCenterY()));
final byte z = (byte) (pos.z() - Math.floor(getCenterZ()));
packet.records[i * 3 + 0] = x;
packet.records[i * 3 + 1] = y;
packet.records[i * 3 + 2] = z;
@ -96,7 +96,7 @@ public abstract class Explosion {
* stored in the packet before this call, but you are free to modify 'records' to modify the blocks sent to the client.
* Just be careful, you might just crash the server or the client. Or you're lucky, both at the same time.
*/
protected void postExplosion(Instance instance, List<BlockPosition> blocks, ExplosionPacket packet) {
protected void postExplosion(Instance instance, List<Point> blocks, ExplosionPacket packet) {
}
/**
@ -106,6 +106,6 @@ public abstract class Explosion {
* @param instance the instance in which the explosion occurs
* @param blocks the block positions returned by prepare
*/
protected void postSend(Instance instance, List<BlockPosition> blocks) {
protected void postSend(Instance instance, List<Point> blocks) {
}
}

View File

@ -6,6 +6,8 @@ import net.minestom.server.MinecraftServer;
import net.minestom.server.Tickable;
import net.minestom.server.UpdateManager;
import net.minestom.server.adventure.audience.PacketGroupingAudience;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.Entity;
@ -29,12 +31,9 @@ import net.minestom.server.storage.StorageLocation;
import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagHandler;
import net.minestom.server.thread.ThreadProvider;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.entity.EntityUtils;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit;
@ -309,10 +308,10 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
* <p>
* Always returning false allow entities to survive in the void.
*
* @param position the position in the world
* @return true iif position is inside the void
* @param point the point in the world
* @return true if the point is inside the void
*/
public abstract boolean isInVoid(@NotNull Position position);
public abstract boolean isInVoid(@NotNull Point point);
/**
* Gets if the instance has been registered in {@link InstanceManager}.
@ -533,27 +532,27 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
}
/**
* Loads the chunk at the given {@link Position} with a callback.
* Loads the chunk at the given {@link Point} with a callback.
*
* @param position the chunk position
* @param point the chunk position
* @param callback the optional callback to run when the chunk is loaded
*/
public void loadChunk(@NotNull Position position, @Nullable ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate(position.getX());
final int chunkZ = ChunkUtils.getChunkCoordinate(position.getZ());
public void loadChunk(@NotNull Point point, @Nullable ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate(point.x());
final int chunkZ = ChunkUtils.getChunkCoordinate(point.z());
loadChunk(chunkX, chunkZ, callback);
}
/**
* Loads a {@link Chunk} (if {@link #hasEnabledAutoChunkLoad()} returns true)
* at the given {@link Position} with a callback.
* at the given {@link Point} with a callback.
*
* @param position the chunk position
* @param point the chunk position
* @param callback the optional callback executed when the chunk is loaded (or with a null chunk if not)
*/
public void loadOptionalChunk(@NotNull Position position, @Nullable ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate(position.getX());
final int chunkZ = ChunkUtils.getChunkCoordinate(position.getZ());
public void loadOptionalChunk(@NotNull Point point, @Nullable ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate(point.x());
final int chunkZ = ChunkUtils.getChunkCoordinate(point.z());
loadOptionalChunk(chunkX, chunkZ, callback);
}
@ -586,7 +585,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
* @param actionParam the action parameter, depends on the block
* @see <a href="https://wiki.vg/Protocol#Block_Action">BlockActionPacket</a> for the action id &amp; param
*/
public void sendBlockAction(@NotNull BlockPosition blockPosition, byte actionId, byte actionParam) {
public void sendBlockAction(@NotNull Point blockPosition, byte actionId, byte actionParam) {
final Block block = getBlock(blockPosition);
BlockActionPacket blockActionPacket = new BlockActionPacket();
@ -601,14 +600,13 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
}
/**
* Gets the {@link Chunk} at the given {@link BlockPosition}, null if not loaded.
* Gets the {@link Chunk} at the given block position, null if not loaded.
*
* @param x the X position
* @param z the Z position
* @return the chunk at the given position, null if not loaded
*/
@Nullable
public Chunk getChunkAt(double x, double z) {
public @Nullable Chunk getChunkAt(double x, double z) {
final int chunkX = ChunkUtils.getChunkCoordinate(x);
final int chunkZ = ChunkUtils.getChunkCoordinate(z);
return getChunk(chunkX, chunkZ);
@ -620,8 +618,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
* @param point the chunk position
* @return the chunk at the given position, null if not loaded
*/
@Nullable
public Chunk getChunkAt(@NotNull Point point) {
public @Nullable Chunk getChunkAt(@NotNull Point point) {
return getChunkAt(point.x(), point.z());
}
@ -703,7 +700,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
}
AddEntityToInstanceEvent event = new AddEntityToInstanceEvent(this, entity);
EventDispatcher.callCancellable(event, () -> {
final Position entityPosition = entity.getPosition();
final Pos entityPosition = entity.getPosition();
final boolean isPlayer = entity instanceof Player;
if (isPlayer) {

View File

@ -1,6 +1,8 @@
package net.minestom.server.instance;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.data.Data;
import net.minestom.server.data.SerializableData;
import net.minestom.server.entity.Player;
@ -19,12 +21,10 @@ import net.minestom.server.network.packet.server.play.UnloadChunkPacket;
import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.callback.OptionalCallback;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkSupplier;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.validate.Check;
import net.minestom.server.world.DimensionType;
import net.minestom.server.world.biomes.Biome;
@ -60,7 +60,7 @@ public class InstanceContainer extends Instance {
protected final Set<Chunk> scheduledChunksToRemove = new HashSet<>();
private final ReadWriteLock changingBlockLock = new ReentrantReadWriteLock();
private final Map<BlockPosition, Block> currentlyChangingBlocks = new HashMap<>();
private final Map<Point, Block> currentlyChangingBlocks = new HashMap<>();
// the chunk loader, used when trying to load/save a chunk from another source
private IChunkLoader chunkLoader;
@ -138,7 +138,7 @@ public class InstanceContainer extends Instance {
synchronized (chunk) {
// Refresh the last block change time
this.lastBlockChangeTime = System.currentTimeMillis();
final BlockPosition blockPosition = new BlockPosition(x, y, z);
final Vec blockPosition = new Vec(x, y, z);
if (isAlreadyChanged(blockPosition, block)) { // do NOT change the block again.
// Avoids StackOverflowExceptions when onDestroy tries to destroy the block itself
// This can happen with nether portals which break the entire frame when a portal block is broken
@ -385,9 +385,9 @@ public class InstanceContainer extends Instance {
}
@Override
public boolean isInVoid(@NotNull Position position) {
public boolean isInVoid(@NotNull Point point) {
// TODO: customizable
return position.getY() < -64;
return point.y() < -64;
}
/**
@ -566,7 +566,7 @@ public class InstanceContainer extends Instance {
}
/**
* Sends a {@link BlockChangePacket} at the specified {@link BlockPosition} to set the block as {@code blockStateId}.
* Sends a {@link BlockChangePacket} at the specified position to set the block as {@code blockStateId}.
* <p>
* WARNING: this does not change the internal block data, this is strictly visual for the players.
*
@ -574,7 +574,7 @@ public class InstanceContainer extends Instance {
* @param blockPosition the block position
* @param block the new block
*/
private void sendBlockChange(@NotNull Chunk chunk, @NotNull BlockPosition blockPosition, @NotNull Block block) {
private void sendBlockChange(@NotNull Chunk chunk, @NotNull Point blockPosition, @NotNull Block block) {
chunk.sendPacketToViewers(new BlockChangePacket(blockPosition, block.stateId()));
}
@ -638,7 +638,7 @@ public class InstanceContainer extends Instance {
}
}
private void setAlreadyChanged(@NotNull BlockPosition blockPosition, Block block) {
private void setAlreadyChanged(@NotNull Point blockPosition, Block block) {
currentlyChangingBlocks.put(blockPosition, block);
}
@ -650,7 +650,7 @@ public class InstanceContainer extends Instance {
* @param block the block
* @return true if the block changed since the last update
*/
private boolean isAlreadyChanged(@NotNull BlockPosition blockPosition, @NotNull Block block) {
private boolean isAlreadyChanged(@NotNull Point blockPosition, @NotNull Block block) {
final Block changedBlock = currentlyChangingBlocks.get(blockPosition);
if (changedBlock == null)
return false;
@ -664,7 +664,7 @@ public class InstanceContainer extends Instance {
* @param blockPosition the block position
* @return the modified block state id
*/
private Block executeBlockPlacementRule(Block block, @NotNull BlockPosition blockPosition) {
private Block executeBlockPlacementRule(Block block, @NotNull Point blockPosition) {
final BlockPlacementRule blockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(block);
if (blockPlacementRule != null) {
return blockPlacementRule.blockUpdate(this, blockPosition, block);
@ -679,15 +679,15 @@ public class InstanceContainer extends Instance {
*
* @param blockPosition the position of the modified block
*/
private void executeNeighboursBlockPlacementRule(@NotNull BlockPosition blockPosition) {
private void executeNeighboursBlockPlacementRule(@NotNull Point blockPosition) {
for (int offsetX = -1; offsetX < 2; offsetX++) {
for (int offsetY = -1; offsetY < 2; offsetY++) {
for (int offsetZ = -1; offsetZ < 2; offsetZ++) {
if (offsetX == 0 && offsetY == 0 && offsetZ == 0)
continue;
final int neighborX = blockPosition.getX() + offsetX;
final int neighborY = blockPosition.getY() + offsetY;
final int neighborZ = blockPosition.getZ() + offsetZ;
final int neighborX = blockPosition.blockX() + offsetX;
final int neighborY = blockPosition.blockY() + offsetY;
final int neighborZ = blockPosition.blockZ() + offsetZ;
final Chunk chunk = getChunkAt(neighborX, neighborZ);
// Do not try to get neighbour in an unloaded chunk
@ -697,7 +697,7 @@ public class InstanceContainer extends Instance {
final Block neighborBlock = chunk.getBlock(neighborX, neighborY, neighborZ);
final BlockPlacementRule neighborBlockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(neighborBlock);
if (neighborBlockPlacementRule != null) {
final BlockPosition neighborPosition = new BlockPosition(neighborX, neighborY, neighborZ);
final Vec neighborPosition = new Vec(neighborX, neighborY, neighborZ);
final Block newNeighborBlock = neighborBlockPlacementRule.blockUpdate(this,
neighborPosition, neighborBlock);
if (neighborBlock != newNeighborBlock) {

View File

@ -4,9 +4,8 @@ import net.minestom.server.entity.Player;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -119,8 +118,8 @@ public class SharedInstance extends Instance {
}
@Override
public boolean isInVoid(@NotNull Position position) {
return instanceContainer.isInVoid(position);
public boolean isInVoid(@NotNull Point point) {
return instanceContainer.isInVoid(point);
}
/**

View File

@ -5,7 +5,7 @@ import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
/**
@ -159,14 +159,13 @@ public class WorldBorder {
/**
* Used to check at which axis does the position collides with the world border.
*
* @param position the position to check
* @param point the point to check
* @return the axis where the position collides with the world border
*/
@NotNull
public CollisionAxis getCollisionAxis(@NotNull Position position) {
public @NotNull CollisionAxis getCollisionAxis(@NotNull Point point) {
final double radius = getDiameter() / 2d;
final boolean checkX = position.getX() <= getCenterX() + radius && position.getX() >= getCenterX() - radius;
final boolean checkZ = position.getZ() <= getCenterZ() + radius && position.getZ() >= getCenterZ() - radius;
final boolean checkX = point.x() <= getCenterX() + radius && point.x() >= getCenterX() - radius;
final boolean checkZ = point.z() <= getCenterZ() + radius && point.z() >= getCenterZ() - radius;
if (!checkX && !checkZ) {
return CollisionAxis.BOTH;
} else if (!checkX) {
@ -180,11 +179,11 @@ public class WorldBorder {
/**
* Used to know if a position is located inside the world border or not.
*
* @param position the position to check
* @param point the point to check
* @return true if {@code position} is inside the world border, false otherwise
*/
public boolean isInside(@NotNull Position position) {
return getCollisionAxis(position) == CollisionAxis.NONE;
public boolean isInside(@NotNull Point point) {
return getCollisionAxis(point) == CollisionAxis.NONE;
}
/**

View File

@ -2,9 +2,9 @@ package net.minestom.server.instance.batch;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -106,8 +106,8 @@ public class RelativeBlockBatch implements Batch<Runnable> {
* @param callback The callback to be executed when the batch is applied
* @return The inverse of this batch, if inverse is enabled in the {@link BatchOption}
*/
public AbsoluteBlockBatch apply(@NotNull Instance instance, @NotNull BlockPosition position, @Nullable Runnable callback) {
return apply(instance, position.getX(), position.getY(), position.getZ(), callback);
public AbsoluteBlockBatch apply(@NotNull Instance instance, @NotNull Point position, @Nullable Runnable callback) {
return apply(instance, position.blockX(), position.blockY(), position.blockZ(), callback);
}
/**

View File

@ -1,6 +1,6 @@
package net.minestom.server.instance.block;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
public interface BlockGetter {

View File

@ -5,7 +5,7 @@ import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.tag.Tag;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

View File

@ -1,8 +1,8 @@
package net.minestom.server.instance.block;
import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.batch.Batch;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
/**
@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull;
public interface BlockSetter {
void setBlock(int x, int y, int z, @NotNull Block block);
default void setBlock(@NotNull BlockPosition blockPosition, @NotNull Block block) {
setBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), block);
default void setBlock(@NotNull Point blockPosition, @NotNull Block block) {
setBlock(blockPosition.blockX(), blockPosition.blockY(), blockPosition.blockZ(), block);
}
}

View File

@ -4,7 +4,7 @@ import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

View File

@ -5,7 +5,7 @@ import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
public class AxisPlacementRule extends BlockPlacementRule {

View File

@ -6,7 +6,7 @@ import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.utils.block.BlockUtils;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import java.util.Map;

View File

@ -1,13 +1,14 @@
package net.minestom.server.instance.block.rule.vanilla;
import it.unimi.dsi.fastutil.Pair;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -51,26 +52,26 @@ public class StairsPlacementRule extends BlockPlacementRule {
private enum Facing {
NORTH(
new BlockPosition(0, 0, 1),
new BlockPosition(0, 0, -1)
new Vec(0, 0, 1),
new Vec(0, 0, -1)
),
EAST(
new BlockPosition(-1, 0, 0),
new BlockPosition(1, 0, 0)
new Vec(-1, 0, 0),
new Vec(1, 0, 0)
),
SOUTH(
new BlockPosition(0, 0, -1),
new BlockPosition(0, 0, 1)
new Vec(0, 0, -1),
new Vec(0, 0, 1)
),
WEST(
new BlockPosition(1, 0, 0),
new BlockPosition(-1, 0, 0)
new Vec(1, 0, 0),
new Vec(-1, 0, 0)
);
private final BlockPosition front;
private final BlockPosition back;
private final Point front;
private final Point back;
Facing(@NotNull BlockPosition front, @NotNull BlockPosition back) {
Facing(@NotNull Point front, @NotNull Point back) {
this.front = front;
this.back = back;
}
@ -83,12 +84,12 @@ public class StairsPlacementRule extends BlockPlacementRule {
}
@NotNull
public Pair<@Nullable Shape, @Nullable Facing> getBack(@NotNull Instance instance, @NotNull BlockPosition blockPosition) {
return this.getProperties(instance, blockPosition.clone().add(this.back));
public Pair<@Nullable Shape, @Nullable Facing> getBack(@NotNull Instance instance, @NotNull Point blockPosition) {
return this.getProperties(instance, blockPosition.add(this.back));
}
@NotNull
private Pair<@Nullable Shape, @Nullable Facing> getProperties(@NotNull Instance instance, @NotNull BlockPosition blockPosition) {
private Pair<@Nullable Shape, @Nullable Facing> getProperties(@NotNull Instance instance, @NotNull Point blockPosition) {
Block block = instance.getBlock(blockPosition);
if (block.isAir()) {
return Pair.of(null, null);
@ -155,7 +156,7 @@ public class StairsPlacementRule extends BlockPlacementRule {
@NotNull
private Facing getFacing(@NotNull Player player) {
float degrees = (player.getPosition().getYaw() - 90) % 360;
float degrees = (player.getPosition().yaw() - 90) % 360;
if (degrees < 0) {
degrees += 360;
}

View File

@ -5,7 +5,7 @@ import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import java.util.Map;

View File

@ -1,8 +1,9 @@
package net.minestom.server.item.metadata;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.item.ItemMeta;
import net.minestom.server.item.ItemMetaBuilder;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
@ -13,12 +14,12 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
private final boolean lodestoneTracked;
private final String lodestoneDimension;
private final Position lodestonePosition;
private final Point lodestonePosition;
protected CompassMeta(ItemMetaBuilder metaBuilder,
boolean lodestoneTracked,
@Nullable String lodestoneDimension,
@Nullable Position lodestonePosition) {
@Nullable Point lodestonePosition) {
super(metaBuilder);
this.lodestoneTracked = lodestoneTracked;
this.lodestoneDimension = lodestoneDimension;
@ -33,7 +34,7 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
return lodestoneDimension;
}
public @Nullable Position getLodestonePosition() {
public @Nullable Point getLodestonePosition() {
return lodestonePosition;
}
@ -41,7 +42,7 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
private boolean lodestoneTracked;
private String lodestoneDimension;
private Position lodestonePosition;
private Point lodestonePosition;
public Builder lodestoneTracked(boolean lodestoneTracked) {
this.lodestoneTracked = lodestoneTracked;
@ -63,15 +64,15 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
return this;
}
public Builder lodestonePosition(@Nullable Position lodestonePosition) {
public Builder lodestonePosition(@Nullable Point lodestonePosition) {
this.lodestonePosition = lodestonePosition;
mutateNbt(compound -> {
if (lodestonePosition != null) {
NBTCompound posCompound = new NBTCompound();
posCompound.setInt("X", (int) lodestonePosition.getX());
posCompound.setInt("Y", (int) lodestonePosition.getY());
posCompound.setInt("Z", (int) lodestonePosition.getZ());
posCompound.setInt("X", lodestonePosition.blockX());
posCompound.setInt("Y", lodestonePosition.blockY());
posCompound.setInt("Z", lodestonePosition.blockZ());
compound.set("LodestonePos", posCompound);
} else {
compound.removeTag("LodestonePos");
@ -99,7 +100,7 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
final int x = posCompound.getInt("X");
final int y = posCompound.getInt("Y");
final int z = posCompound.getInt("Z");
lodestonePosition(new Position(x, y, z));
lodestonePosition(new Vec(x, y, z));
}
}

View File

@ -24,8 +24,8 @@ import net.minestom.server.network.packet.client.play.ClientPlayerBlockPlacement
import net.minestom.server.network.packet.server.play.BlockChangePacket;
import net.minestom.server.utils.Direction;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.utils.validate.Check;
import java.util.Set;

View File

@ -13,8 +13,7 @@ import net.minestom.server.item.ItemStack;
import net.minestom.server.item.StackingRule;
import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket;
import net.minestom.server.network.packet.server.play.AcknowledgePlayerDiggingPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
public class PlayerDiggingListener {
@ -150,11 +149,10 @@ public class PlayerDiggingListener {
if (!result) {
if (block.isSolid()) {
final BlockPosition playerBlockPosition = player.getPosition().toBlockPosition();
final var playerPosition = player.getPosition();
// Teleport the player back if he broke a solid block just below him
if (playerBlockPosition.subtract(0, 1, 0).equals(blockPosition))
player.teleport(player.getPosition());
if (playerPosition.sub(0, 1, 0).samePoint(blockPosition))
player.teleport(playerPosition);
}
}
}

View File

@ -5,8 +5,8 @@ import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.network.packet.client.play.*;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
public class PlayerPositionListener {
@ -16,10 +16,10 @@ public class PlayerPositionListener {
}
public static void playerLookListener(ClientPlayerRotationPacket packet, Player player) {
final Position playerPosition = player.getPosition();
final double x = playerPosition.getX();
final double y = playerPosition.getY();
final double z = playerPosition.getZ();
final var playerPosition = player.getPosition();
final double x = playerPosition.x();
final double y = playerPosition.y();
final double z = playerPosition.z();
final float yaw = packet.yaw;
final float pitch = packet.pitch;
final boolean onGround = packet.onGround;
@ -27,9 +27,9 @@ public class PlayerPositionListener {
}
public static void playerPositionListener(ClientPlayerPositionPacket packet, Player player) {
final Position playerPosition = player.getPosition();
final float yaw = playerPosition.getYaw();
final float pitch = playerPosition.getPitch();
final var playerPosition = player.getPosition();
final float yaw = playerPosition.yaw();
final float pitch = playerPosition.pitch();
final boolean onGround = packet.onGround;
processMovement(player,
packet.x, packet.y, packet.z,
@ -53,46 +53,35 @@ public class PlayerPositionListener {
private static void processMovement(@NotNull Player player, double x, double y, double z,
float yaw, float pitch, boolean onGround) {
final Instance instance = player.getInstance();
// Prevent moving before the player spawned, probably a modified client (or high latency?)
if (instance == null) {
return;
}
// Prevent the player from moving during a teleport
if (player.getLastSentTeleportId() != player.getLastReceivedTeleportId()) {
return;
}
// Try to move in an unloaded chunk, prevent it
if (!ChunkUtils.isLoaded(instance, x, z)) {
player.teleport(player.getPosition());
return;
}
final Position currentPosition = player.getPosition().clone();
Position newPosition = new Position(x, y, z, yaw, pitch);
final Position cachedPosition = newPosition.clone();
final var currentPosition = player.getPosition();
final var newPosition = new Pos(x, y, z, yaw, pitch);
PlayerMoveEvent playerMoveEvent = new PlayerMoveEvent(player, newPosition);
EventDispatcher.call(playerMoveEvent);
// True if the event call changed the player position (possibly a teleport)
final boolean positionChanged = !currentPosition.equals(player.getPosition());
if (!playerMoveEvent.isCancelled() && !positionChanged) {
// Move the player
newPosition = playerMoveEvent.getNewPosition();
if (!newPosition.equals(cachedPosition)) {
// New position from the event changed, teleport the player
player.teleport(newPosition);
}
// Change the internal data
player.refreshPosition(newPosition);
player.refreshPosition(playerMoveEvent.getNewPosition());
player.refreshOnGround(onGround);
} else {
// Cancelled, teleport to previous position
player.teleport(player.getPosition());
}
}
}

View File

@ -6,7 +6,7 @@ import net.minestom.server.entity.metadata.other.BoatMeta;
import net.minestom.server.network.packet.client.play.ClientSteerBoatPacket;
import net.minestom.server.network.packet.client.play.ClientSteerVehiclePacket;
import net.minestom.server.network.packet.client.play.ClientVehicleMovePacket;
import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Pos;
public class PlayerVehicleListener {
@ -19,11 +19,10 @@ public class PlayerVehicleListener {
public static void vehicleMoveListener(ClientVehicleMovePacket packet, Player player) {
final Entity vehicle = player.getVehicle();
if (vehicle == null)
return;
final Position newPosition = new Position((float) packet.x, (float) packet.y, (float) packet.z, packet.yaw, packet.pitch);
final var newPosition = new Pos(packet.x, packet.y, packet.z, packet.yaw, packet.pitch);
vehicle.refreshPosition(newPosition);
// This packet causes weird screen distortion
@ -39,7 +38,6 @@ public class PlayerVehicleListener {
public static void boatSteerListener(ClientSteerBoatPacket packet, Player player) {
final Entity vehicle = player.getVehicle();
if (!(vehicle.getEntityMeta() instanceof BoatMeta))
return;
@ -47,5 +45,4 @@ public class PlayerVehicleListener {
boat.setLeftPaddleTurning(packet.leftPaddleTurning);
boat.setRightPaddleTurning(packet.rightPaddleTurning);
}
}

View File

@ -3,8 +3,8 @@ package net.minestom.server.network.packet.client.play;
import net.minestom.server.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class ClientGenerateStructurePacket extends ClientPlayPacket {

View File

@ -3,11 +3,10 @@ package net.minestom.server.network.packet.client.play;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class ClientPlayerBlockPlacementPacket extends ClientPlayPacket {

View File

@ -4,8 +4,8 @@ import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class ClientPlayerDiggingPacket extends ClientPlayPacket {

View File

@ -3,8 +3,8 @@ package net.minestom.server.network.packet.client.play;
import net.minestom.server.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class ClientQueryBlockNbtPacket extends ClientPlayPacket {

View File

@ -3,8 +3,8 @@ package net.minestom.server.network.packet.client.play;
import net.minestom.server.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class ClientUpdateCommandBlockPacket extends ClientPlayPacket {

View File

@ -3,8 +3,8 @@ package net.minestom.server.network.packet.client.play;
import net.minestom.server.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class ClientUpdateSignPacket extends ClientPlayPacket {

View File

@ -4,8 +4,8 @@ import net.minestom.server.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.Rotation;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class ClientUpdateStructureBlockPacket extends ClientPlayPacket {

View File

@ -5,8 +5,8 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class AcknowledgePlayerDiggingPacket implements ServerPacket {

View File

@ -4,8 +4,8 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class BlockActionPacket implements ServerPacket {

View File

@ -4,8 +4,8 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class BlockBreakAnimationPacket implements ServerPacket {

View File

@ -4,8 +4,8 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class BlockChangePacket implements ServerPacket {

View File

@ -5,8 +5,8 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBT;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;

View File

@ -10,7 +10,6 @@ import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.tag.Tag;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Utils;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
@ -147,11 +146,11 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket {
}
if (resultNbt.getSize() > 0) {
final BlockPosition blockPosition = ChunkUtils.getBlockPosition(index, chunkX, chunkZ);
final var blockPosition = ChunkUtils.getBlockPosition(index, chunkX, chunkZ);
resultNbt.setString("id", handler.getNamespaceId().asString())
.setInt("x", blockPosition.getX())
.setInt("y", blockPosition.getY())
.setInt("z", blockPosition.getZ());
.setInt("x", blockPosition.blockX())
.setInt("y", blockPosition.blockY())
.setInt("z", blockPosition.blockZ());
compounds.add(resultNbt);
}
}

View File

@ -4,8 +4,8 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class EffectPacket implements ServerPacket {

View File

@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
public class EntityPositionAndRotationPacket implements ServerPacket {
@ -14,7 +14,8 @@ public class EntityPositionAndRotationPacket implements ServerPacket {
public float yaw, pitch;
public boolean onGround;
public EntityPositionAndRotationPacket() {}
public EntityPositionAndRotationPacket() {
}
@Override
public void write(@NotNull BinaryWriter writer) {
@ -44,15 +45,15 @@ public class EntityPositionAndRotationPacket implements ServerPacket {
}
public static EntityPositionAndRotationPacket getPacket(int entityId,
@NotNull Position newPosition, @NotNull Position oldPosition,
@NotNull Pos newPosition, @NotNull Pos oldPosition,
boolean onGround) {
EntityPositionAndRotationPacket entityPositionAndRotationPacket = new EntityPositionAndRotationPacket();
entityPositionAndRotationPacket.entityId = entityId;
entityPositionAndRotationPacket.deltaX = (short) ((newPosition.getX() * 32 - oldPosition.getX() * 32) * 128);
entityPositionAndRotationPacket.deltaY = (short) ((newPosition.getY() * 32 - oldPosition.getY() * 32) * 128);
entityPositionAndRotationPacket.deltaZ = (short) ((newPosition.getZ() * 32 - oldPosition.getZ() * 32) * 128);
entityPositionAndRotationPacket.yaw = newPosition.getYaw();
entityPositionAndRotationPacket.pitch = newPosition.getPitch();
entityPositionAndRotationPacket.deltaX = (short) ((newPosition.x() * 32 - oldPosition.x() * 32) * 128);
entityPositionAndRotationPacket.deltaY = (short) ((newPosition.y() * 32 - oldPosition.y() * 32) * 128);
entityPositionAndRotationPacket.deltaZ = (short) ((newPosition.z() * 32 - oldPosition.z() * 32) * 128);
entityPositionAndRotationPacket.yaw = newPosition.yaw();
entityPositionAndRotationPacket.pitch = newPosition.pitch();
entityPositionAndRotationPacket.onGround = onGround;
return entityPositionAndRotationPacket;

View File

@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
public class EntityPositionPacket implements ServerPacket {
@ -13,7 +13,8 @@ public class EntityPositionPacket implements ServerPacket {
public short deltaX, deltaY, deltaZ;
public boolean onGround;
public EntityPositionPacket() {}
public EntityPositionPacket() {
}
@Override
public void write(@NotNull BinaryWriter writer) {
@ -40,13 +41,13 @@ public class EntityPositionPacket implements ServerPacket {
@NotNull
public static EntityPositionPacket getPacket(int entityId,
@NotNull Position newPosition, @NotNull Position oldPosition,
@NotNull Pos newPosition, @NotNull Pos oldPosition,
boolean onGround) {
EntityPositionPacket entityPositionPacket = new EntityPositionPacket();
entityPositionPacket.entityId = entityId;
entityPositionPacket.deltaX = (short) ((newPosition.getX() * 32 - oldPosition.getX() * 32) * 128);
entityPositionPacket.deltaY = (short) ((newPosition.getY() * 32 - oldPosition.getY() * 32) * 128);
entityPositionPacket.deltaZ = (short) ((newPosition.getZ() * 32 - oldPosition.getZ() * 32) * 128);
entityPositionPacket.deltaX = (short) ((newPosition.x() * 32 - oldPosition.x() * 32) * 128);
entityPositionPacket.deltaY = (short) ((newPosition.y() * 32 - oldPosition.y() * 32) * 128);
entityPositionPacket.deltaZ = (short) ((newPosition.z() * 32 - oldPosition.z() * 32) * 128);
entityPositionPacket.onGround = onGround;
return entityPositionPacket;

View File

@ -2,42 +2,42 @@ package net.minestom.server.network.packet.server.play;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
public class EntityTeleportPacket implements ServerPacket {
public int entityId;
public Position position;
public Pos position;
public boolean onGround;
public EntityTeleportPacket() {
position = new Position();
position = Pos.ZERO;
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(entityId);
writer.writeDouble(position.getX());
writer.writeDouble(position.getY());
writer.writeDouble(position.getZ());
writer.writeByte((byte) (position.getYaw() * 256f / 360f));
writer.writeByte((byte) (position.getPitch() * 256f / 360f));
writer.writeDouble(position.x());
writer.writeDouble(position.y());
writer.writeDouble(position.z());
writer.writeByte((byte) (position.yaw() * 256f / 360f));
writer.writeByte((byte) (position.pitch() * 256f / 360f));
writer.writeBoolean(onGround);
}
@Override
public void read(@NotNull BinaryReader reader) {
entityId = reader.readVarInt();
position = new Position(
position = new Pos(
reader.readDouble(),
reader.readDouble(),
reader.readDouble(),
reader.readByte() * 360f / 256f,
reader.readByte() * 360f / 256f
);
);
onGround = reader.readBoolean();
}

View File

@ -4,8 +4,8 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class OpenSignEditorPacket implements ServerPacket {

View File

@ -2,30 +2,30 @@ package net.minestom.server.network.packet.server.play;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
public class PlayerPositionAndLookPacket implements ServerPacket {
public Position position;
public Pos position;
public byte flags;
public int teleportId;
public boolean dismountVehicle;
public PlayerPositionAndLookPacket() {
position = new Position();
position = Pos.ZERO;
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeDouble(position.getX());
writer.writeDouble(position.getY());
writer.writeDouble(position.getZ());
writer.writeDouble(position.x());
writer.writeDouble(position.y());
writer.writeDouble(position.z());
writer.writeFloat(position.getYaw());
writer.writeFloat(position.getPitch());
writer.writeFloat(position.yaw());
writer.writeFloat(position.pitch());
writer.writeByte(flags);
writer.writeVarInt(teleportId);
@ -34,7 +34,7 @@ public class PlayerPositionAndLookPacket implements ServerPacket {
@Override
public void read(@NotNull BinaryReader reader) {
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble(), reader.readFloat(), reader.readFloat());
position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(), reader.readFloat(), reader.readFloat());
flags = reader.readByte();
teleportId = reader.readVarInt();

View File

@ -1,5 +1,6 @@
package net.minestom.server.network.packet.server.play;
import net.minestom.server.coordinate.Point;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.BlockPosition;
@ -9,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
public class SculkVibrationSignal implements ServerPacket {
public BlockPosition position;
public Point position;
public String destinationIdentifier;
// TODO 'varies' destination
public int arrivalTicks;

View File

@ -5,9 +5,9 @@ import net.minestom.server.adventure.AdventurePacketConvertor;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.sound.SoundEvent;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
public class SoundEffectPacket implements ServerPacket {
@ -23,18 +23,19 @@ public class SoundEffectPacket implements ServerPacket {
}
@NotNull
public static SoundEffectPacket create(Source category, SoundEvent sound, Position position, float volume, float pitch) {
public static SoundEffectPacket create(Source category, SoundEvent sound, Pos position, float volume, float pitch) {
SoundEffectPacket packet = new SoundEffectPacket();
packet.soundId = sound.getId();
packet.soundSource = category;
// *8 converts to fixed-point representation with 3 bits for fractional part
packet.x = (int) position.getX();
packet.y = (int) position.getY();
packet.z = (int) position.getZ();
packet.x = (int) position.x();
packet.y = (int) position.y();
packet.z = (int) position.z();
packet.volume = volume;
packet.pitch = pitch;
return packet;
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(soundId);
@ -50,9 +51,9 @@ public class SoundEffectPacket implements ServerPacket {
public void read(@NotNull BinaryReader reader) {
soundId = reader.readVarInt();
soundSource = Source.values()[reader.readVarInt()];
x = reader.readInt()/8;
y = reader.readInt()/8;
z = reader.readInt()/8;
x = reader.readInt() / 8;
y = reader.readInt() / 8;
z = reader.readInt() / 8;
volume = reader.readFloat();
pitch = reader.readFloat();
}

View File

@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
@ -14,13 +14,13 @@ public class SpawnEntityPacket implements ServerPacket {
public int entityId;
public UUID uuid;
public int type;
public Position position;
public Pos position;
public int data;
public short velocityX, velocityY, velocityZ;
public SpawnEntityPacket() {
uuid = new UUID(0, 0);
position = new Position();
position = Pos.ZERO;
}
@Override
@ -29,12 +29,12 @@ public class SpawnEntityPacket implements ServerPacket {
writer.writeUuid(uuid);
writer.writeVarInt(type);
writer.writeDouble(position.getX());
writer.writeDouble(position.getY());
writer.writeDouble(position.getZ());
writer.writeDouble(position.x());
writer.writeDouble(position.y());
writer.writeDouble(position.z());
writer.writeByte((byte) (position.getYaw() * 256 / 360));
writer.writeByte((byte) (position.getPitch() * 256 / 360));
writer.writeByte((byte) (position.yaw() * 256 / 360));
writer.writeByte((byte) (position.pitch() * 256 / 360));
writer.writeInt(data);
@ -49,10 +49,9 @@ public class SpawnEntityPacket implements ServerPacket {
uuid = reader.readUuid();
type = reader.readVarInt();
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble());
position.setYaw(reader.readByte() * 360f / 256f);
position.setPitch(reader.readByte() * 360f / 256f);
position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(),
reader.readByte() * 360f / 256f,
reader.readByte() * 360f / 256f);
data = reader.readInt();

View File

@ -2,34 +2,34 @@ package net.minestom.server.network.packet.server.play;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
public class SpawnExperienceOrbPacket implements ServerPacket {
public int entityId;
public Position position;
public Pos position;
public short expCount;
public SpawnExperienceOrbPacket() {
position = new Position();
position = Pos.ZERO;
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(entityId);
writer.writeDouble(position.getX());
writer.writeDouble(position.getY());
writer.writeDouble(position.getZ());
writer.writeDouble(position.x());
writer.writeDouble(position.y());
writer.writeDouble(position.z());
writer.writeShort(expCount);
}
@Override
public void read(@NotNull BinaryReader reader) {
entityId = reader.readVarInt();
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble());
position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble());
expCount = reader.readShort();
}

View File

@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
@ -14,13 +14,13 @@ public class SpawnLivingEntityPacket implements ServerPacket {
public int entityId;
public UUID entityUuid;
public int entityType;
public Position position;
public Pos position;
public float headPitch;
public short velocityX, velocityY, velocityZ;
public SpawnLivingEntityPacket() {
entityUuid = new UUID(0, 0);
position = new Position();
position = Pos.ZERO;
}
@Override
@ -29,12 +29,12 @@ public class SpawnLivingEntityPacket implements ServerPacket {
writer.writeUuid(entityUuid);
writer.writeVarInt(entityType);
writer.writeDouble(position.getX());
writer.writeDouble(position.getY());
writer.writeDouble(position.getZ());
writer.writeDouble(position.x());
writer.writeDouble(position.y());
writer.writeDouble(position.z());
writer.writeByte((byte) (position.getYaw() * 256 / 360));
writer.writeByte((byte) (position.getPitch() * 256 / 360));
writer.writeByte((byte) (position.yaw() * 256 / 360));
writer.writeByte((byte) (position.pitch() * 256 / 360));
writer.writeByte((byte) (headPitch * 256 / 360));
writer.writeShort(velocityX);
@ -48,10 +48,9 @@ public class SpawnLivingEntityPacket implements ServerPacket {
entityUuid = reader.readUuid();
entityType = reader.readVarInt();
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble());
position.setYaw(reader.readByte() * 360f / 256f);
position.setPitch(reader.readByte() * 360f / 256f);
position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(),
reader.readByte() * 360f / 256f,
reader.readByte() * 360f / 256f);
headPitch = reader.readByte() * 360f / 256f;
velocityX = reader.readShort();

View File

@ -4,8 +4,8 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;

View File

@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
@ -13,31 +13,31 @@ public class SpawnPlayerPacket implements ServerPacket {
public int entityId;
public UUID playerUuid;
public Position position;
public Pos position;
public SpawnPlayerPacket() {
playerUuid = new UUID(0,0);
position = new Position();
playerUuid = new UUID(0, 0);
position = Pos.ZERO;
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(entityId);
writer.writeUuid(playerUuid);
writer.writeDouble(position.getX());
writer.writeDouble(position.getY());
writer.writeDouble(position.getZ());
writer.writeByte((byte) (position.getYaw() * 256f / 360f));
writer.writeByte((byte) (position.getPitch() * 256f / 360f));
writer.writeDouble(position.x());
writer.writeDouble(position.y());
writer.writeDouble(position.z());
writer.writeByte((byte) (position.yaw() * 256f / 360f));
writer.writeByte((byte) (position.pitch() * 256f / 360f));
}
@Override
public void read(@NotNull BinaryReader reader) {
entityId = reader.readVarInt();
playerUuid = reader.readUuid();
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble());
position.setYaw((reader.readByte() * 360f) / 256f);
position.setPitch((reader.readByte() * 360f) / 256f);
this.entityId = reader.readVarInt();
this.playerUuid = reader.readUuid();
this.position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(),
(reader.readByte() * 360f) / 256f,
(reader.readByte() * 360f) / 256f);
}
@Override

View File

@ -4,8 +4,8 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
public class SpawnPositionPacket implements ServerPacket {

View File

@ -1,8 +1,7 @@
package net.minestom.server.utils;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.clone.PublicCloneable;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@ -13,7 +12,7 @@ import java.util.function.DoubleUnaryOperator;
/**
* Represents the position of a block, so with integers instead of floating numbers.
*
* @deprecated use {@link net.minestom.server.utils.coordinate.Vec} instead
* @deprecated use {@link net.minestom.server.coordinate.Vec} instead
*/
@Deprecated
public class BlockPosition implements Point {

View File

@ -1,7 +1,7 @@
package net.minestom.server.utils;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@ -11,7 +11,7 @@ import java.util.function.DoubleUnaryOperator;
* Represents a position.
* The instance is not contained.
*
* @deprecated use {@link net.minestom.server.utils.coordinate.Pos} instead
* @deprecated use {@link net.minestom.server.coordinate.Pos} instead
*/
@Deprecated
public class Position implements Point {

View File

@ -1,7 +1,7 @@
package net.minestom.server.utils;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
public final class SerializerUtils {

View File

@ -1,14 +1,12 @@
package net.minestom.server.utils;
import net.minestom.server.MinecraftServer;
import net.minestom.server.utils.clone.PublicCloneable;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import java.util.function.DoubleUnaryOperator;
/**
* @deprecated use {@link net.minestom.server.utils.coordinate.Vec} instead
* @deprecated use {@link net.minestom.server.coordinate.Vec} instead
*/
@Deprecated
public class Vector implements Point {

View File

@ -6,11 +6,10 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.NBTUtils;
import net.minestom.server.utils.SerializerUtils;
import net.minestom.server.utils.Utils;
import net.minestom.server.utils.coordinate.Point;
import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBT;

Some files were not shown because too many files have changed in this diff Show More