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

View File

@ -1,6 +1,7 @@
package net.minestom.demo.largeframebuffers; package net.minestom.demo.largeframebuffers;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode; import net.minestom.server.entity.GameMode;
import net.minestom.server.event.player.PlayerLoginEvent; import net.minestom.server.event.player.PlayerLoginEvent;
import net.minestom.server.event.player.PlayerSpawnEvent; 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.batch.ChunkBatch;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.network.ConnectionManager; import net.minestom.server.network.ConnectionManager;
import net.minestom.server.utils.Position;
import net.minestom.server.world.biomes.Biome; import net.minestom.server.world.biomes.Biome;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -35,12 +35,12 @@ public class MainDemo {
// Set the spawning instance // Set the spawning instance
player.addEventCallback(PlayerLoginEvent.class, event -> { player.addEventCallback(PlayerLoginEvent.class, event -> {
event.setSpawningInstance(instanceContainer); event.setSpawningInstance(instanceContainer);
player.setRespawnPoint(new Position(0, 45, 0)); player.setRespawnPoint(new Pos(0, 45, 0));
}); });
// Teleport the player at spawn // Teleport the player at spawn
player.addEventCallback(PlayerSpawnEvent.class, event -> { player.addEventCallback(PlayerSpawnEvent.class, event -> {
player.teleport(new Position(0, 45, 0)); player.teleport(new Pos(0, 45, 0));
player.setGameMode(GameMode.CREATIVE); 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.network.packet.server.play.StopSoundPacket;
import net.minestom.server.registry.Registries; import net.minestom.server.registry.Registries;
import net.minestom.server.sound.SoundEvent; import net.minestom.server.sound.SoundEvent;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection; import java.util.Collection;
@ -25,6 +24,7 @@ import java.util.Collection;
*/ */
public class AdventurePacketConvertor { public class AdventurePacketConvertor {
private static final Object2IntMap<NamedTextColor> NAMED_TEXT_COLOR_ID_MAP = new Object2IntArrayMap<>(16); private static final Object2IntMap<NamedTextColor> NAMED_TEXT_COLOR_ID_MAP = new Object2IntArrayMap<>(16);
static { static {
NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.BLACK, 0); NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.BLACK, 0);
NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.DARK_BLUE, 1); 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. * Creates a sound packet from a sound and a location.
* *
* @param sound the sound * @param sound the sound
* @param x the x coordinate * @param x the x coordinate
* @param y the y coordinate * @param y the y coordinate
* @param z the z coordinate * @param z the z coordinate
* @return the sound packet * @return the sound packet
*/ */
public static @NotNull ServerPacket createSoundPacket(@NotNull Sound sound, double x, double y, double z) { 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. * 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} * @param emitter the emitter, must be an {@link Entity}
* @return the sound packet * @return the sound packet
*/ */
@ -158,14 +158,13 @@ public class AdventurePacketConvertor {
packet.pitch = sound.pitch(); packet.pitch = sound.pitch();
return packet; return packet;
} else { } else {
final Position pos = entity.getPosition(); final var pos = entity.getPosition();
final NamedSoundEffectPacket packet = new NamedSoundEffectPacket(); final NamedSoundEffectPacket packet = new NamedSoundEffectPacket();
packet.soundName = sound.name().asString(); packet.soundName = sound.name().asString();
packet.soundSource = sound.source(); packet.soundSource = sound.source();
packet.x = (int) pos.getX(); packet.x = (int) pos.x();
packet.y = (int) pos.getY(); packet.y = (int) pos.y();
packet.z = (int) pos.getX(); packet.z = (int) pos.z();
packet.volume = sound.volume(); packet.volume = sound.volume();
packet.pitch = sound.pitch(); packet.pitch = sound.pitch();
return packet; return packet;
@ -175,7 +174,7 @@ public class AdventurePacketConvertor {
/** /**
* Creates an entity sound packet from an Adventure sound. * 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 * @param entity the entity the sound is coming from
* @return the packet * @return the packet
* @deprecated Use {@link #createSoundPacket(Sound, Sound.Emitter)} * @deprecated Use {@link #createSoundPacket(Sound, Sound.Emitter)}

View File

@ -1,9 +1,8 @@
package net.minestom.server.collision; 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.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; 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 * @param blockPosition the position to check
* @return true if the bounding box intersects with the position, false otherwise * @return true if the bounding box intersects with the position, false otherwise
@ -150,7 +149,7 @@ public class BoundingBox {
* @return the min X * @return the min X
*/ */
public double getMinX() { 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 * @return the max X
*/ */
public double getMaxX() { 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 * @return the min Y
*/ */
public double getMinY() { public double getMinY() {
return entity.getPosition().getY(); return entity.getPosition().y();
} }
/** /**
@ -177,7 +176,7 @@ public class BoundingBox {
* @return the max Y * @return the max Y
*/ */
public double getMaxY() { public double getMaxY() {
return entity.getPosition().getY() + y; return entity.getPosition().y() + y;
} }
/** /**
@ -186,7 +185,7 @@ public class BoundingBox {
* @return the min Z * @return the min Z
*/ */
public double getMinZ() { 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 * @return the max Z
*/ */
public double getMaxZ() { 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} * @return the points at the bottom of the {@link BoundingBox}
*/ */
@NotNull @NotNull
public Vector[] getBottomFace() { public Vec[] getBottomFace() {
return new Vector[]{ return new Vec[]{
new Vector(getMinX(), getMinY(), getMinZ()), new Vec(getMinX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMinY(), getMinZ()), new Vec(getMaxX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMinY(), getMaxZ()), new Vec(getMaxX(), getMinY(), getMaxZ()),
new Vector(getMinX(), 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} * @return the points at the top of the {@link BoundingBox}
*/ */
@NotNull @NotNull
public Vector[] getTopFace() { public Vec[] getTopFace() {
return new Vector[]{ return new Vec[]{
new Vector(getMinX(), getMaxY(), getMinZ()), new Vec(getMinX(), getMaxY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMinZ()), new Vec(getMaxX(), getMaxY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMaxZ()), new Vec(getMaxX(), getMaxY(), getMaxZ()),
new Vector(getMinX(), 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} * @return the points on the left face of the {@link BoundingBox}
*/ */
@NotNull @NotNull
public Vector[] getLeftFace() { public Vec[] getLeftFace() {
return new Vector[]{ return new Vec[]{
new Vector(getMinX(), getMinY(), getMinZ()), new Vec(getMinX(), getMinY(), getMinZ()),
new Vector(getMinX(), getMaxY(), getMinZ()), new Vec(getMinX(), getMaxY(), getMinZ()),
new Vector(getMinX(), getMaxY(), getMaxZ()), new Vec(getMinX(), getMaxY(), getMaxZ()),
new Vector(getMinX(), getMinY(), 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} * @return the points on the right face of the {@link BoundingBox}
*/ */
@NotNull @NotNull
public Vector[] getRightFace() { public Vec[] getRightFace() {
return new Vector[]{ return new Vec[]{
new Vector(getMaxX(), getMinY(), getMinZ()), new Vec(getMaxX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMinZ()), new Vec(getMaxX(), getMaxY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMaxZ()), new Vec(getMaxX(), getMaxY(), getMaxZ()),
new Vector(getMaxX(), getMinY(), 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} * @return the points at the front of the {@link BoundingBox}
*/ */
@NotNull @NotNull
public Vector[] getFrontFace() { public Vec[] getFrontFace() {
return new Vector[]{ return new Vec[]{
new Vector(getMinX(), getMinY(), getMinZ()), new Vec(getMinX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMinY(), getMinZ()), new Vec(getMaxX(), getMinY(), getMinZ()),
new Vector(getMaxX(), getMaxY(), getMinZ()), new Vec(getMaxX(), getMaxY(), getMinZ()),
new Vector(getMinX(), 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} * @return the points at the back of the {@link BoundingBox}
*/ */
@NotNull @NotNull
public Vector[] getBackFace() { public Vec[] getBackFace() {
return new Vector[]{ return new Vec[]{
new Vector(getMinX(), getMinY(), getMaxZ()), new Vec(getMinX(), getMinY(), getMaxZ()),
new Vector(getMaxX(), getMinY(), getMaxZ()), new Vec(getMaxX(), getMinY(), getMaxZ()),
new Vector(getMaxX(), getMaxY(), getMaxZ()), new Vec(getMaxX(), getMaxY(), getMaxZ()),
new Vector(getMinX(), 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.Instance;
import net.minestom.server.instance.WorldBorder; import net.minestom.server.instance.WorldBorder;
import net.minestom.server.instance.block.Block; 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.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; import org.jetbrains.annotations.NotNull;
public class CollisionUtils { public class CollisionUtils {
private static final Vector Y_AXIS = new Vector(0, 1, 0); private static final Vec Y_AXIS = new Vec(0, 1, 0);
private static final Vector X_AXIS = new Vector(1, 0, 0); private static final Vec X_AXIS = new Vec(1, 0, 0);
private static final Vector Z_AXIS = new Vector(0, 0, 1); private static final Vec Z_AXIS = new Vec(0, 0, 1);
/** /**
* Moves an entity with physics applied (ie checking against blocks) * Moves an entity with physics applied (ie checking against blocks)
* *
* @param entity the entity to move * @param entity the entity to move
* @param deltaPosition * @return the result of physics simulation
* @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
*/ */
public static boolean handlePhysics(@NotNull Entity entity, public static PhysicsResult handlePhysics(@NotNull Entity entity, @NotNull Vec deltaPosition) {
@NotNull Vector deltaPosition,
@NotNull Position positionOut,
@NotNull Vector velocityOut) {
// TODO handle collisions with nearby entities (should it be done here?) // TODO handle collisions with nearby entities (should it be done here?)
final Instance instance = entity.getInstance(); final Instance instance = entity.getInstance();
final Chunk originChunk = entity.getChunk(); final Chunk originChunk = entity.getChunk();
final Position currentPosition = entity.getPosition(); final Pos currentPosition = entity.getPosition();
final BoundingBox boundingBox = entity.getBoundingBox(); final BoundingBox boundingBox = entity.getBoundingBox();
Vector intermediaryPosition = new Vector(); final StepResult yCollision = stepAxis(instance, originChunk, currentPosition.asVec(), Y_AXIS, deltaPosition.y(),
boolean yCollision = stepAxis(instance, originChunk, currentPosition.toVector(), Y_AXIS, deltaPosition.getY(), deltaPosition.y() > 0 ? boundingBox.getTopFace() : boundingBox.getBottomFace());
intermediaryPosition,
deltaPosition.getY() > 0 ? boundingBox.getTopFace() : boundingBox.getBottomFace());
boolean xCollision = stepAxis(instance, originChunk, intermediaryPosition, X_AXIS, deltaPosition.getX(), final StepResult xCollision = stepAxis(instance, originChunk, yCollision.newPosition, X_AXIS, deltaPosition.x(),
intermediaryPosition, deltaPosition.x() < 0 ? boundingBox.getLeftFace() : boundingBox.getRightFace());
deltaPosition.getX() < 0 ? boundingBox.getLeftFace() : boundingBox.getRightFace());
boolean zCollision = stepAxis(instance, originChunk, intermediaryPosition, Z_AXIS, deltaPosition.getZ(), final StepResult zCollision = stepAxis(instance, originChunk, xCollision.newPosition, Z_AXIS, deltaPosition.z(),
intermediaryPosition, deltaPosition.z() > 0 ? boundingBox.getBackFace() : boundingBox.getFrontFace());
deltaPosition.getZ() > 0 ? boundingBox.getBackFace() : boundingBox.getFrontFace());
positionOut.setX(intermediaryPosition.getX()); return new PhysicsResult(currentPosition.withCoord(zCollision.newPosition),
positionOut.setY(intermediaryPosition.getY()); deltaPosition.apply(((x, y, z) -> new Vec(
positionOut.setZ(intermediaryPosition.getZ()); xCollision.foundCollision ? 0 : x,
velocityOut.copy(deltaPosition); yCollision.foundCollision ? 0 : y,
if (xCollision) { zCollision.foundCollision ? 0 : z
velocityOut.setX(0f); ))), yCollision.foundCollision && deltaPosition.y() < 0);
}
if (yCollision) {
velocityOut.setY(0f);
}
if (zCollision) {
velocityOut.setZ(0f);
}
return yCollision && deltaPosition.getY() < 0;
} }
/** /**
@ -74,111 +55,77 @@ public class CollisionUtils {
* @param startPosition starting position for stepping, can be intermediary position from last step * @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 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 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 * @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, private static StepResult stepAxis(Instance instance, Chunk originChunk, Vec startPosition, Vec axis, double stepAmount, Vec... corners) {
Chunk originChunk,
Vector startPosition, Vector axis,
double stepAmount, Vector positionOut,
Vector... corners) {
positionOut.copy(startPosition);
if (corners.length == 0) if (corners.length == 0)
return false; // avoid degeneracy in following computations return new StepResult(startPosition, 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]);
}
final Vec[] originalCorners = corners.clone();
final double sign = Math.signum(stepAmount); final double sign = Math.signum(stepAmount);
final int blockLength = (int) stepAmount; final int blockLength = (int) stepAmount;
final double remainingLength = stepAmount - blockLength; final double remainingLength = stepAmount - blockLength;
// used to determine if 'remainingLength' should be used // used to determine if 'remainingLength' should be used
boolean collisionFound = false; boolean collisionFound = false;
for (int i = 0; i < Math.abs(blockLength); i++) { for (int i = 0; i < Math.abs(blockLength); i++) {
if (!stepOnce(instance, originChunk, axis, sign, cornersCopy, cornerPositions)) { if (collisionFound = stepOnce(instance, originChunk, axis, sign, corners)) break;
collisionFound = true;
}
if (collisionFound) {
break;
}
} }
// add remainingLength // add remainingLength
if (!collisionFound) { if (!collisionFound) {
Vector direction = new Vector(); collisionFound = stepOnce(instance, originChunk, axis, remainingLength, corners);
direction.copy(axis);
collisionFound = !stepOnce(instance, originChunk, direction, remainingLength, cornersCopy, cornerPositions);
} }
// find the corner which moved the least // find the corner which moved the least
double smallestDisplacement = Double.POSITIVE_INFINITY; double smallestDisplacement = Double.POSITIVE_INFINITY;
for (int i = 0; i < corners.length; i++) { 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) { if (displacement < smallestDisplacement) {
smallestDisplacement = displacement; smallestDisplacement = displacement;
} }
} }
positionOut.copy(startPosition); return new StepResult(startPosition.add(new Vec(smallestDisplacement).mul(axis).mul(sign)), collisionFound);
positionOut.add(smallestDisplacement * axis.getX() * sign, smallestDisplacement * axis.getY() * sign, smallestDisplacement * axis.getZ() * sign);
return collisionFound;
} }
/** /**
* Steps once (by a length of 1 block) on the given axis. * Steps once (by a length of 1 block) on the given axis.
* *
* @param instance instance to get blocks from * @param instance instance to get blocks from
* @param axis the axis to move along * @param axis the axis to move along
* @param amount * @param corners the corners of the bounding box to consider
* @param cornersCopy the corners of the bounding box to consider (mutable) * @return true if found collision
* @param cornerPositions the corners, converted to BlockPosition (mutable)
* @return false if this method encountered a collision
*/ */
private static boolean stepOnce(Instance instance, private static boolean stepOnce(Instance instance, Chunk originChunk, Vec axis, double amount, Vec[] corners) {
Chunk originChunk,
Vector axis, double amount, Vector[] cornersCopy, BlockPosition[] cornerPositions) {
final double sign = Math.signum(amount); final double sign = Math.signum(amount);
for (int cornerIndex = 0; cornerIndex < cornersCopy.length; cornerIndex++) { for (int cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) {
Vector corner = cornersCopy[cornerIndex]; final Vec originalCorner = corners[cornerIndex];
BlockPosition blockPos = cornerPositions[cornerIndex]; final Vec newCorner = originalCorner.add(axis.mul(amount));
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()));
Chunk chunk = ChunkUtils.retrieve(instance, originChunk, blockPos); Chunk chunk = ChunkUtils.retrieve(instance, originChunk, newCorner);
if (!ChunkUtils.isLoaded(chunk)) { if (!ChunkUtils.isLoaded(chunk)) {
// Collision at chunk border // 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: block collision boxes
// TODO: for the moment, always consider a full block // TODO: for the moment, always consider a full block
if (block.isSolid()) { 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) { return true;
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;
} }
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) * @return the position with the world border collision applied (can be {@code newPosition} if not changed)
*/ */
@NotNull @NotNull
public static Position applyWorldBorder(@NotNull Instance instance, public static Point applyWorldBorder(@NotNull Instance instance,
@NotNull Position currentPosition, @NotNull Position newPosition) { @NotNull Point currentPosition, @NotNull Point newPosition) {
final WorldBorder worldBorder = instance.getWorldBorder(); final WorldBorder worldBorder = instance.getWorldBorder();
final WorldBorder.CollisionAxis collisionAxis = worldBorder.getCollisionAxis(newPosition); final WorldBorder.CollisionAxis collisionAxis = worldBorder.getCollisionAxis(newPosition);
switch (collisionAxis) { switch (collisionAxis) {
@ -200,15 +147,48 @@ public class CollisionUtils {
return newPosition; return newPosition;
case BOTH: case BOTH:
// Apply Y velocity/gravity // Apply Y velocity/gravity
return new Position(currentPosition.getX(), newPosition.getY(), currentPosition.getZ()); return new Vec(currentPosition.x(), newPosition.y(), currentPosition.z());
case X: case X:
// Apply Y/Z velocity/gravity // 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: case Z:
// Apply X/Y velocity/gravity // 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..."); 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.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException; 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.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.StringUtils;
import net.minestom.server.utils.location.RelativeVec;
import org.jetbrains.annotations.NotNull; 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> * <p>
* Example: 5 ~ -3 * Example: 5 ~ -3
*/ */
public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBlockPosition> { public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeVec> {
public ArgumentRelativeBlockPosition(@NotNull String id) { public ArgumentRelativeBlockPosition(@NotNull String id) {
super(id, 3); super(id, 3);
@ -21,19 +21,17 @@ public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBloc
@NotNull @NotNull
@Override @Override
public RelativeBlockPosition parse(@NotNull String input) throws ArgumentSyntaxException { public RelativeVec parse(@NotNull String input) throws ArgumentSyntaxException {
final String[] split = input.split(StringUtils.SPACE); final String[] split = input.split(StringUtils.SPACE);
// Check if the value has enough element to be correct // Check if the value has enough element to be correct
if (split.length != getNumberCount()) { if (split.length != getNumberCount()) {
throw new ArgumentSyntaxException("Invalid number of values", input, INVALID_NUMBER_COUNT_ERROR); 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 relativeX = false;
boolean relativeY = false; boolean relativeY = false;
boolean relativeZ = false; boolean relativeZ = false;
for (int i = 0; i < split.length; i++) { for (int i = 0; i < split.length; i++) {
final String element = split[i]; final String element = split[i];
if (element.startsWith(RELATIVE_CHAR)) { if (element.startsWith(RELATIVE_CHAR)) {
@ -51,11 +49,11 @@ public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBloc
final String potentialNumber = element.substring(1); final String potentialNumber = element.substring(1);
final int number = Integer.parseInt(potentialNumber); final int number = Integer.parseInt(potentialNumber);
if (i == 0) { if (i == 0) {
blockPosition.setX(number); x = number;
} else if (i == 1) { } else if (i == 1) {
blockPosition.setY(number); y = number;
} else if (i == 2) { } else if (i == 2) {
blockPosition.setZ(number); z = number;
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new ArgumentSyntaxException("Invalid number", input, INVALID_NUMBER_ERROR); throw new ArgumentSyntaxException("Invalid number", input, INVALID_NUMBER_ERROR);
@ -66,11 +64,11 @@ public class ArgumentRelativeBlockPosition extends ArgumentRelative<RelativeBloc
try { try {
final int number = Integer.parseInt(element); final int number = Integer.parseInt(element);
if (i == 0) { if (i == 0) {
blockPosition.setX(number); x = number;
} else if (i == 1) { } else if (i == 1) {
blockPosition.setY(number); y = number;
} else if (i == 2) { } else if (i == 2) {
blockPosition.setZ(number); z = number;
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new ArgumentSyntaxException("Invalid number", input, INVALID_NUMBER_ERROR); 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 @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.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException; 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.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.StringUtils;
import net.minestom.server.utils.location.RelativeVec;
import org.jetbrains.annotations.NotNull; 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> * <p>
* Example: -1.2 ~ * Example: -1.2 ~
*/ */
@ -23,13 +23,12 @@ public class ArgumentRelativeVec2 extends ArgumentRelative<RelativeVec> {
@Override @Override
public RelativeVec parse(@NotNull String input) throws ArgumentSyntaxException { public RelativeVec parse(@NotNull String input) throws ArgumentSyntaxException {
final String[] split = input.split(StringUtils.SPACE); final String[] split = input.split(StringUtils.SPACE);
// Check if the value has enough element to be correct // Check if the value has enough element to be correct
if (split.length != getNumberCount()) { if (split.length != getNumberCount()) {
throw new ArgumentSyntaxException("Invalid number of values", input, INVALID_NUMBER_COUNT_ERROR); 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 relativeX = false;
boolean relativeZ = false; boolean relativeZ = false;
@ -47,18 +46,18 @@ public class ArgumentRelativeVec2 extends ArgumentRelative<RelativeVec> {
final String potentialNumber = element.substring(1); final String potentialNumber = element.substring(1);
final float number = Float.parseFloat(potentialNumber); final float number = Float.parseFloat(potentialNumber);
if (i == 0) { if (i == 0) {
vector.setX(number); x = number;
} else if (i == 1) { } else if (i == 1) {
vector.setZ(number); z = number;
} }
} }
} else { } else {
final float number = Float.parseFloat(element); final float number = Float.parseFloat(element);
if (i == 0) { if (i == 0) {
vector.setX(number); x = number;
} else if (i == 1) { } else if (i == 1) {
vector.setZ(number); z = number;
} }
} }
} catch (NumberFormatException e) { } 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 @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.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException; 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.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.StringUtils;
import net.minestom.server.utils.location.RelativeVec;
import org.jetbrains.annotations.NotNull; 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> * <p>
* Example: -1.2 ~ 5 * Example: -1.2 ~ 5
*/ */
@ -23,17 +23,15 @@ public class ArgumentRelativeVec3 extends ArgumentRelative<RelativeVec> {
@Override @Override
public RelativeVec parse(@NotNull String input) throws ArgumentSyntaxException { public RelativeVec parse(@NotNull String input) throws ArgumentSyntaxException {
final String[] split = input.split(StringUtils.SPACE); final String[] split = input.split(StringUtils.SPACE);
// Check if the value has enough element to be correct // Check if the value has enough element to be correct
if (split.length != getNumberCount()) { if (split.length != getNumberCount()) {
throw new ArgumentSyntaxException("Invalid number of values", input, INVALID_NUMBER_COUNT_ERROR); 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 relativeX = false;
boolean relativeY = false; boolean relativeY = false;
boolean relativeZ = false; boolean relativeZ = false;
for (int i = 0; i < split.length; i++) { for (int i = 0; i < split.length; i++) {
final String element = split[i]; final String element = split[i];
try { try {
@ -50,22 +48,22 @@ public class ArgumentRelativeVec3 extends ArgumentRelative<RelativeVec> {
final String potentialNumber = element.substring(1); final String potentialNumber = element.substring(1);
final float number = Float.parseFloat(potentialNumber); final float number = Float.parseFloat(potentialNumber);
if (i == 0) { if (i == 0) {
vector.setX(number); x = number;
} else if (i == 1) { } else if (i == 1) {
vector.setY(number); y = number;
} else if (i == 2) { } else if (i == 2) {
vector.setZ(number); z = number;
} }
} }
} else { } else {
final float number = Float.parseFloat(element); final float number = Float.parseFloat(element);
if (i == 0) { if (i == 0) {
vector.setX(number); x = number;
} else if (i == 1) { } else if (i == 1) {
vector.setY(number); y = number;
} else if (i == 2) { } else if (i == 2) {
vector.setZ(number); z = number;
} }
} }
} catch (NumberFormatException e) { } 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 @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.MathUtils;
import net.minestom.server.utils.chunk.ChunkUtils;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -109,6 +111,25 @@ public interface Point {
@Contract(pure = true) @Contract(pure = true)
@NotNull Point div(double value); @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 * 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 * 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(y() - point.y()) +
MathUtils.square(z() - point.z()); 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.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.function.DoubleUnaryOperator; import java.util.function.DoubleUnaryOperator;
/** /**
@ -11,6 +15,8 @@ import java.util.function.DoubleUnaryOperator;
* To become record and primitive. * To become record and primitive.
*/ */
public final class Pos implements Point { public final class Pos implements Point {
public static final Pos ZERO = new Pos(0, 0, 0);
private final double x, y, z; private final double x, y, z;
private final float yaw, pitch; private final float yaw, pitch;
@ -34,6 +40,12 @@ public final class Pos implements Point {
this(point, 0, 0); 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) @Contract(pure = true)
public @NotNull Pos withCoord(double x, double y, double z) { public @NotNull Pos withCoord(double x, double y, double z) {
return new Pos(x, y, z, yaw, pitch); 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); 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) @Contract(pure = true)
public @NotNull Pos withYaw(float yaw) { public @NotNull Pos withYaw(float yaw) {
return new Pos(x, y, z, yaw, pitch); 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)); 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 @Override
@Contract(pure = true) @Contract(pure = true)
public double x() { public double x() {
@ -188,6 +253,11 @@ public final class Pos implements Point {
return div(value, value, value); return div(value, value, value);
} }
@Override
public @NotNull Pos relative(@NotNull BlockFace face) {
return (Pos) Point.super.relative(face);
}
@Contract(pure = true) @Contract(pure = true)
public float yaw() { public float yaw() {
return yaw; return yaw;
@ -203,6 +273,34 @@ public final class Pos implements Point {
return new Vec(x, y, z); 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 @FunctionalInterface
public interface Operator { public interface Operator {
@NotNull Pos apply(double x, double y, double z); @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 net.minestom.server.utils.MathUtils;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Objects; import java.util.Objects;
import java.util.function.DoubleUnaryOperator; import java.util.function.DoubleUnaryOperator;
import java.util.function.UnaryOperator;
/** /**
* Represents an immutable 3D vector. * Represents an immutable 3D vector.
@ -58,7 +58,7 @@ public final class Vec implements Point {
* @return the created point * @return the created point
*/ */
@Contract(pure = true) @Contract(pure = true)
public @NotNull Vec with(@NotNull Operator operator) { public @NotNull Vec apply(@NotNull Operator operator) {
return operator.apply(x, y, z); return operator.apply(x, y, z);
} }
@ -158,6 +158,11 @@ public final class Vec implements Point {
return div(value, value, value); return div(value, value, value);
} }
@Override
public @NotNull Vec relative(@NotNull BlockFace face) {
return (Vec) Point.super.relative(face);
}
@Contract(pure = true) @Contract(pure = true)
public @NotNull Vec neg() { public @NotNull Vec neg() {
return new Vec(-x, -y, -z); 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)); 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) @Contract(pure = true)
public @NotNull Pos asPosition() { public @NotNull Pos asPosition() {
return new Pos(x, y, z); return new Pos(x, y, z);
@ -392,6 +392,21 @@ public final class Vec implements Point {
@FunctionalInterface @FunctionalInterface
public interface Operator { 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); @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.chat.JsonMessage;
import net.minestom.server.collision.BoundingBox; import net.minestom.server.collision.BoundingBox;
import net.minestom.server.collision.CollisionUtils; 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.Data;
import net.minestom.server.data.DataContainer; import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.metadata.EntityMeta; 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.Tag;
import net.minestom.server.tag.TagHandler; import net.minestom.server.tag.TagHandler;
import net.minestom.server.thread.ThreadProvider; 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.callback.OptionalCallback;
import net.minestom.server.utils.chunk.ChunkCallback; import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils; 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.entity.EntityUtils;
import net.minestom.server.utils.player.PlayerUtils; import net.minestom.server.utils.player.PlayerUtils;
import net.minestom.server.utils.time.Cooldown; import net.minestom.server.utils.time.Cooldown;
@ -77,16 +77,8 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
protected Instance instance; protected Instance instance;
protected Chunk currentChunk; protected Chunk currentChunk;
protected final Position position; protected Pos position;
/** protected Pos lastSyncedPosition;
* 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 boolean onGround; protected boolean onGround;
private BoundingBox boundingBox; private BoundingBox boundingBox;
@ -94,7 +86,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
protected Entity vehicle; protected Entity vehicle;
// Velocity // 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; protected boolean hasPhysics = true;
/** /**
@ -159,9 +151,8 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
this.id = generateId(); this.id = generateId();
this.entityType = entityType; this.entityType = entityType;
this.uuid = uuid; this.uuid = uuid;
this.position = new Position(); this.position = Pos.ZERO;
this.lastPosition = new Position(); this.lastSyncedPosition = Pos.ZERO;
this.lastSyncedPosition = new Position();
setBoundingBox(entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); setBoundingBox(entityType.getWidth(), entityType.getHeight(), entityType.getWidth());
@ -181,18 +172,6 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
this(entityType, UUID.randomUUID()); 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. * 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}). * 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 * @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 * @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!"); 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) -> { final ChunkCallback endCallback = (chunk) -> {
refreshPosition(teleportPosition); refreshPosition(position);
synchronizePosition(true); synchronizePosition(true);
OptionalCallback.execute(callback); OptionalCallback.execute(callback);
}; };
if (chunks == null || chunks.length == 0) { if (chunks == null || chunks.length == 0) {
instance.loadOptionalChunk(teleportPosition, endCallback); instance.loadOptionalChunk(position, endCallback);
} else { } else {
ChunkUtils.optionalLoadAll(instance, chunks, null, endCallback); 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); teleport(position, null, callback);
} }
public void teleport(@NotNull Position position) { public void teleport(@NotNull Pos position) {
teleport(position, null); teleport(position, null);
} }
@ -316,7 +290,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* @param pitch the new pitch * @param pitch the new pitch
*/ */
public void setView(float yaw, float pitch) { public void setView(float yaw, float pitch) {
refreshView(yaw, pitch); this.position = position.withView(yaw, pitch);
EntityRotationPacket entityRotationPacket = new EntityRotationPacket(); EntityRotationPacket entityRotationPacket = new EntityRotationPacket();
entityRotationPacket.entityId = getEntityId(); entityRotationPacket.entityId = getEntityId();
@ -332,16 +306,6 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
sendPacketToViewersAndSelf(entityRotationPacket); 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. * 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 * 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 entityHeadLookPacket = new EntityHeadLookPacket();
entityHeadLookPacket.entityId = getEntityId(); entityHeadLookPacket.entityId = getEntityId();
entityHeadLookPacket.yaw = position.getYaw(); entityHeadLookPacket.yaw = position.yaw();
playerConnection.sendPacket(entityHeadLookPacket); playerConnection.sendPacket(entityHeadLookPacket);
} }
@ -510,9 +474,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
} }
} }
sendPositionUpdate(false);
final boolean isNettyClient = PlayerUtils.isNettyClient(this); final boolean isNettyClient = PlayerUtils.isNettyClient(this);
// Entity tick // Entity tick
{ {
@ -532,30 +494,34 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
if (applyVelocity) { if (applyVelocity) {
final float tps = MinecraftServer.TICK_PER_SECOND; final float tps = MinecraftServer.TICK_PER_SECOND;
final double newX = position.getX() + velocity.getX() / tps; final Pos newPosition;
final double newY = position.getY() + velocity.getY() / tps; final Vec newVelocity;
final double newZ = position.getZ() + velocity.getZ() / tps;
Position newPosition = new Position(newX, newY, newZ);
Vector newVelocityOut = new Vector();
// Gravity force // Gravity force
final double gravityY = hasNoGravity() ? 0 : gravityAcceleration; final double gravityY = hasNoGravity() ? 0 : gravityAcceleration;
final Vector deltaPos = new Vector( final Vec deltaPos = new Vec(
getVelocity().getX() / tps, getVelocity().x() / tps,
getVelocity().getY() / tps - gravityY, getVelocity().y() / tps - gravityY,
getVelocity().getZ() / tps getVelocity().z() / tps
); );
if (this.hasPhysics) { 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 { } 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 // 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); final Chunk finalChunk = ChunkUtils.retrieve(instance, currentChunk, finalVelocityPosition);
if (!ChunkUtils.isLoaded(finalChunk)) { if (!ChunkUtils.isLoaded(finalChunk)) {
// Entity shouldn't be updated when moving in an unloaded chunk // 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 // Apply the position if changed
if (!finalVelocityPosition.isSimilar(position)) { if (!finalVelocityPosition.samePoint(position)) {
refreshPosition(finalVelocityPosition.getX(), refreshPosition((Pos) finalVelocityPosition, true);
finalVelocityPosition.getY(),
finalVelocityPosition.getZ());
sendPositionUpdate(true);
} }
// Update velocity // Update velocity
if (hasVelocity() || !newVelocityOut.isZero()) { if (hasVelocity() || !newVelocity.equals(Vec.ZERO)) {
this.velocity.copy(newVelocityOut); if (onGround && isNettyClient) {
this.velocity.multiply(tps);
final Block block = finalChunk.getBlock(position.toBlockPosition());
final double drag = block.registry().friction();
if (onGround) {
// Stop player velocity // Stop player velocity
if (isNettyClient) { velocity = Vec.ZERO;
this.velocity.zero(); } else {
} final Block block = finalChunk.getBlock(position);
} final double drag = block.registry().friction();
this.velocity.setX(velocity.getX() * drag); velocity = newVelocity
this.velocity.setZ(velocity.getZ() * drag); // Convert from blocks/tick to blocks/sec
if (!hasNoGravity()) .mul(tps)
this.velocity.setY(velocity.getY() * (1 - gravityDragPerTick)); // Apply drag
.apply((x, y, z) -> new Vec(
if (velocity.equals(new Vector())) { x * drag,
this.velocity.zero(); !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 * @param clientSide {@code true} if the client triggered this action
*/ */
protected void sendPositionUpdate(final boolean clientSide) { protected void sendPositionUpdate(final boolean clientSide) {
final boolean viewChange = !position.hasSimilarView(lastSyncedPosition); final boolean viewChange = !position.sameView(lastSyncedPosition);
final double distanceX = Math.abs(position.getX() - lastSyncedPosition.getX()); final double distanceX = Math.abs(position.x() - lastSyncedPosition.x());
final double distanceY = Math.abs(position.getY() - lastSyncedPosition.getY()); final double distanceY = Math.abs(position.y() - lastSyncedPosition.y());
final double distanceZ = Math.abs(position.getZ() - lastSyncedPosition.getZ()); final double distanceZ = Math.abs(position.z() - lastSyncedPosition.z());
final boolean positionChange = (distanceX + distanceY + distanceZ) > 0; final boolean positionChange = (distanceX + distanceY + distanceZ) > 0;
if (distanceX > 8 || distanceY > 8 || distanceZ > 8) { if (distanceX > 8 || distanceY > 8 || distanceZ > 8) {
@ -704,7 +665,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
// Fix head rotation // Fix head rotation
final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket(); final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
entityHeadLookPacket.entityId = getEntityId(); entityHeadLookPacket.entityId = getEntityId();
entityHeadLookPacket.yaw = position.getYaw(); entityHeadLookPacket.yaw = position.yaw();
sendPacketToViewersAndSelf(entityHeadLookPacket); sendPacketToViewersAndSelf(entityHeadLookPacket);
} else if (positionChange) { } else if (positionChange) {
final EntityPositionPacket entityPositionPacket = EntityPositionPacket final EntityPositionPacket entityPositionPacket = EntityPositionPacket
@ -713,13 +674,13 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
} else if (viewChange) { } else if (viewChange) {
final EntityRotationPacket entityRotationPacket = new EntityRotationPacket(); final EntityRotationPacket entityRotationPacket = new EntityRotationPacket();
entityRotationPacket.entityId = getEntityId(); entityRotationPacket.entityId = getEntityId();
entityRotationPacket.yaw = position.getYaw(); entityRotationPacket.yaw = position.yaw();
entityRotationPacket.pitch = position.getPitch(); entityRotationPacket.pitch = position.pitch();
entityRotationPacket.onGround = onGround; entityRotationPacket.onGround = onGround;
final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket(); final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
entityHeadLookPacket.entityId = getEntityId(); entityHeadLookPacket.entityId = getEntityId();
entityHeadLookPacket.yaw = position.getYaw(); entityHeadLookPacket.yaw = position.yaw();
if (clientSide) { if (clientSide) {
sendPacketToViewers(entityHeadLookPacket); sendPacketToViewers(entityHeadLookPacket);
@ -736,12 +697,12 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
if (PlayerUtils.isNettyClient(this) && !clientSide) { if (PlayerUtils.isNettyClient(this) && !clientSide) {
final PlayerPositionAndLookPacket playerPositionAndLookPacket = new PlayerPositionAndLookPacket(); final PlayerPositionAndLookPacket playerPositionAndLookPacket = new PlayerPositionAndLookPacket();
playerPositionAndLookPacket.flags = 0b111; playerPositionAndLookPacket.flags = 0b111;
playerPositionAndLookPacket.position = position.clone().subtract(lastSyncedPosition.getX(), lastSyncedPosition.getY(), lastSyncedPosition.getZ()); playerPositionAndLookPacket.position = position.sub(lastSyncedPosition);
playerPositionAndLookPacket.teleportId = ((Player) this).getNextTeleportId(); playerPositionAndLookPacket.teleportId = ((Player) this).getNextTeleportId();
((Player) this).getPlayerConnection().sendPacket(playerPositionAndLookPacket); ((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. * @param spawnPosition the spawn position for the entity.
* @throws IllegalStateException if {@code instance} has not been registered in {@link InstanceManager} * @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(), Check.stateCondition(!instance.isRegistered(),
"Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance"); "Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance");
if (this.instance != null) { if (this.instance != null) {
this.instance.UNSAFE_removeEntity(this); this.instance.UNSAFE_removeEntity(this);
} }
this.position = spawnPosition;
this.position.set(spawnPosition);
this.lastPosition.set(position);
this.isActive = true; this.isActive = true;
this.instance = instance; this.instance = instance;
refreshCurrentChunk(instance.getChunkAt(position.getX(), position.getZ())); refreshCurrentChunk(instance.getChunkAt(position));
instance.UNSAFE_addEntity(this); instance.UNSAFE_addEntity(this);
spawn(); spawn();
EventDispatcher.call(new EntitySpawnEvent(this, instance)); EventDispatcher.call(new EntitySpawnEvent(this, instance));
} }
public void setInstance(@NotNull Instance instance, @NotNull Point spawnPosition) {
setInstance(instance, Pos.fromPoint(spawnPosition));
}
/** /**
* Changes the entity instance. * Changes the entity instance.
* *
@ -928,8 +889,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* *
* @return the entity current velocity * @return the entity current velocity
*/ */
@NotNull public @NotNull Vec getVelocity() {
public Vector getVelocity() {
return velocity; return velocity;
} }
@ -940,10 +900,10 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* *
* @param velocity the new entity velocity * @param velocity the new entity velocity
*/ */
public void setVelocity(@NotNull Vector velocity) { public void setVelocity(@NotNull Vec velocity) {
EntityVelocityEvent entityVelocityEvent = new EntityVelocityEvent(this, velocity); EntityVelocityEvent entityVelocityEvent = new EntityVelocityEvent(this, velocity);
EventDispatcher.callCancellable(entityVelocityEvent, () -> { EventDispatcher.callCancellable(entityVelocityEvent, () -> {
this.velocity.copy(entityVelocityEvent.getVelocity()); this.velocity = entityVelocityEvent.getVelocity();
sendPacketToViewersAndSelf(getVelocityPacket()); sendPacketToViewersAndSelf(getVelocityPacket());
}); });
} }
@ -954,7 +914,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
* @return true if velocity is not set to 0 * @return true if velocity is not set to 0
*/ */
public boolean hasVelocity() { 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} * @return the distance between this and {@code entity}
*/ */
public double getDistance(@NotNull Entity 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} * @return the distance squared between this and {@code entity}
*/ */
public double getDistanceSquared(@NotNull Entity 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); 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 * Used to refresh the entity and its passengers position
* - put the entity in the right instance chunk * - put the entity in the right instance chunk
* - update the viewable chunks (load and unload) * - update the viewable chunks (load and unload)
* - add/remove players from the viewers list if {@link #isAutoViewable()} is enabled * - add/remove players from the viewers list if {@link #isAutoViewable()} is enabled
* <p> * <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 newPosition the new position
* @param y new position Y
* @param z new position Z
*/ */
private void refreshPosition(double x, double y, double z) { private void refreshCoordinate(Point newPosition) {
position.setX(x);
position.setY(y);
position.setZ(z);
if (hasPassenger()) { if (hasPassenger()) {
for (Entity passenger : getPassengers()) { for (Entity passenger : getPassengers()) {
passenger.refreshPosition(x, y, z); passenger.refreshCoordinate(newPosition);
} }
} }
final Instance instance = getInstance(); final Instance instance = getInstance();
if (instance != null) { if (instance != null) {
final int lastChunkX = currentChunk.getChunkX(); final int lastChunkX = currentChunk.getChunkX();
final int lastChunkZ = currentChunk.getChunkZ(); final int lastChunkZ = currentChunk.getChunkZ();
final int newChunkX = ChunkUtils.getChunkCoordinate(newPosition.x());
final int newChunkX = ChunkUtils.getChunkCoordinate(x); final int newChunkZ = ChunkUtils.getChunkCoordinate(newPosition.z());
final int newChunkZ = ChunkUtils.getChunkCoordinate(z);
if (lastChunkX != newChunkX || lastChunkZ != newChunkZ) { if (lastChunkX != newChunkX || lastChunkZ != newChunkZ) {
// Entity moved in a new chunk // Entity moved in a new chunk
final Chunk newChunk = instance.getChunk(newChunkX, newChunkZ); 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); instance.UNSAFE_switchEntityChunk(this, currentChunk, newChunk);
if (this instanceof Player) { if (this instanceof Player) {
// Refresh player view // Refresh player view
@ -1364,45 +1338,9 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
player.refreshVisibleChunks(newChunk); player.refreshVisibleChunks(newChunk);
player.refreshVisibleEntities(newChunk); player.refreshVisibleEntities(newChunk);
} }
refreshCurrentChunk(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 * @return the current position of the entity
*/ */
@NotNull public @NotNull Pos getPosition() {
public Position getPosition() {
return position; return position;
} }
@ -1536,19 +1473,17 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
return scheduledRemoveTime != 0; return scheduledRemoveTime != 0;
} }
@NotNull protected @NotNull Vec getVelocityForPacket() {
protected Vector getVelocityForPacket() { return this.velocity.mul(8000f / MinecraftServer.TICK_PER_SECOND);
return this.velocity.clone().multiply(8000f / MinecraftServer.TICK_PER_SECOND);
} }
@NotNull protected @NotNull EntityVelocityPacket getVelocityPacket() {
protected EntityVelocityPacket getVelocityPacket() {
EntityVelocityPacket velocityPacket = new EntityVelocityPacket(); EntityVelocityPacket velocityPacket = new EntityVelocityPacket();
velocityPacket.entityId = getEntityId(); velocityPacket.entityId = getEntityId();
Vector velocity = getVelocityForPacket(); Vec velocity = getVelocityForPacket();
velocityPacket.velocityX = (short) velocity.getX(); velocityPacket.velocityX = (short) velocity.x();
velocityPacket.velocityY = (short) velocity.getY(); velocityPacket.velocityY = (short) velocity.y();
velocityPacket.velocityZ = (short) velocity.getZ(); velocityPacket.velocityZ = (short) velocity.z();
return velocityPacket; return velocityPacket;
} }
@ -1576,15 +1511,14 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
*/ */
@ApiStatus.Internal @ApiStatus.Internal
protected void synchronizePosition(boolean includeSelf) { protected void synchronizePosition(boolean includeSelf) {
final Position pos = position.clone();
final EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket(); final EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket();
entityTeleportPacket.entityId = getEntityId(); entityTeleportPacket.entityId = getEntityId();
entityTeleportPacket.position = pos; entityTeleportPacket.position = position;
entityTeleportPacket.onGround = isOnGround(); entityTeleportPacket.onGround = isOnGround();
sendPacketToViewers(entityTeleportPacket); sendPacketToViewers(entityTeleportPacket);
this.lastAbsoluteSynchronizationTime = System.currentTimeMillis(); 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) { public void takeKnockback(final float strength, final double x, final double z) {
if (strength > 0) { if (strength > 0) {
//TODO check possible side effects of unnatural TPS (other than 20TPS) //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); final Vec velocityModifier = new Vec(x, z)
this.velocity.setX(velocity.getX() / 2d - velocityModifier.getX()); .normalize()
this.velocity.setY(onGround ? Math.min(.4d, velocity.getY() / 2d + strength) * MinecraftServer.TICK_PER_SECOND : velocity.getY()); .mul(strength * MinecraftServer.TICK_PER_SECOND / 2);
this.velocity.setZ(velocity.getZ() / 2d - velocityModifier.getZ()); 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 com.extollit.gaming.ai.path.HydrazinePathFinder;
import net.minestom.server.attribute.Attribute; 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.EntityAI;
import net.minestom.server.entity.ai.EntityAIGroup; import net.minestom.server.entity.ai.EntityAIGroup;
import net.minestom.server.entity.pathfinding.NavigableEntity; 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.EventDispatcher;
import net.minestom.server.event.entity.EntityAttackEvent; import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -42,20 +42,6 @@ public class EntityCreature extends LivingEntity implements NavigableEntity, Ent
this(entityType, UUID.randomUUID()); 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 @Override
public void update(long time) { public void update(long time) {
// AI // AI
@ -69,7 +55,7 @@ public class EntityCreature extends LivingEntity implements NavigableEntity, Ent
} }
@Override @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())); this.navigator.setPathFinder(new HydrazinePathFinder(navigator.getPathingEntity(), instance.getInstanceSpace()));
super.setInstance(instance, spawnPosition); super.setInstance(instance, spawnPosition);

View File

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

View File

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

View File

@ -1,10 +1,6 @@
package net.minestom.server.entity; package net.minestom.server.entity;
import net.minestom.server.instance.Instance; import net.minestom.server.coordinate.Vec;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Comparator; import java.util.Comparator;
@ -14,22 +10,13 @@ public class ExperienceOrb extends Entity {
private Player target; private Player target;
private long lastTargetUpdateTick; private long lastTargetUpdateTick;
public ExperienceOrb(short experienceCount) {
public ExperienceOrb(short experienceCount, @NotNull Position spawnPosition) { super(EntityType.EXPERIENCE_ORB);
super(EntityType.EXPERIENCE_ORB, spawnPosition);
setBoundingBox(0.5f, 0.5f, 0.5f); setBoundingBox(0.5f, 0.5f, 0.5f);
//todo vanilla sets random velocity here? //todo vanilla sets random velocity here?
this.experienceCount = experienceCount; this.experienceCount = experienceCount;
} }
public ExperienceOrb(short experienceCount, @NotNull Position spawnPosition, @Nullable Instance instance) {
this(experienceCount, spawnPosition);
if (instance != null) {
setInstance(instance);
}
}
@Override @Override
public void update(long time) { public void update(long time) {
@ -44,7 +31,7 @@ public class ExperienceOrb extends Entity {
double d = 8.0; double d = 8.0;
if (lastTargetUpdateTick < time - 20 + getEntityId() % 100) { 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); this.target = getClosestPlayer(this, 8);
} }
@ -56,13 +43,13 @@ public class ExperienceOrb extends Entity {
} }
if (target != null) { if (target != null) {
Position pos = getPosition(); final var pos = getPosition();
Position targetPos = target.getPosition(); final var targetPos = target.getPosition();
Vector toTarget = new Vector(targetPos.getX() - pos.getX(), targetPos.getY() + (target.getEyeHeight() / 2) - pos.getY(), targetPos.getZ() - pos.getZ()); 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 double e = toTarget.length(); //could really be lengthSquared
if (e < 8) { if (e < 8) {
double f = 1 - (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 // apply slipperiness
setVelocity(getVelocity().multiply(new Vector(g, 0.98f, g))); setVelocity(getVelocity().mul(new Vec(g, 0.98f, g)));
if (isOnGround()) if (isOnGround()) {
setVelocity(getVelocity().multiply(new Vector(1, -0.9f, 1))); setVelocity(getVelocity().mul(new Vec(1, -0.9f, 1)));
}
} }
@Override @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.EventDispatcher;
import net.minestom.server.event.entity.EntityItemMergeEvent; import net.minestom.server.event.entity.EntityItemMergeEvent;
import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
import net.minestom.server.item.StackingRule; 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.Cooldown;
import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -41,20 +39,12 @@ public class ItemEntity extends Entity {
private long spawnTime; private long spawnTime;
private long pickupDelay; private long pickupDelay;
public ItemEntity(@NotNull ItemStack itemStack, @NotNull Position spawnPosition) { public ItemEntity(@NotNull ItemStack itemStack) {
super(EntityType.ITEM, spawnPosition); super(EntityType.ITEM);
setItemStack(itemStack); setItemStack(itemStack);
setBoundingBox(0.25f, 0.25f, 0.25f); 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. * 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. * Can be set to null to entirely remove the delay.
* *
* @param mergeUpdateOption the new merge update option * @param mergeUpdateOption the new merge update option
*
* @deprecated Replaced by {@link #setMergeDelay(Duration)} * @deprecated Replaced by {@link #setMergeDelay(Duration)}
*/ */
@SuppressWarnings("removal") @SuppressWarnings("removal")
@ -239,7 +228,7 @@ public class ItemEntity extends Entity {
/** /**
* Sets the pickup delay of the ItemEntity. * Sets the pickup delay of the ItemEntity.
* *
* @param delay the pickup delay * @param delay the pickup delay
* @param temporalUnit the unit of the delay * @param temporalUnit the unit of the delay
*/ */
public void setPickupDelay(long delay, @NotNull TemporalUnit temporalUnit) { public void setPickupDelay(long delay, @NotNull TemporalUnit temporalUnit) {
@ -249,7 +238,7 @@ public class ItemEntity extends Entity {
/** /**
* Sets the pickup delay of the ItemEntity. * Sets the pickup delay of the ItemEntity.
* *
* @param delay the pickup delay * @param delay the pickup delay
*/ */
public void setPickupDelay(Duration delay) { public void setPickupDelay(Duration delay) {
this.pickupDelay = delay.toMillis(); 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.AttributeInstance;
import net.minestom.server.attribute.Attributes; import net.minestom.server.attribute.Attributes;
import net.minestom.server.collision.BoundingBox; 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.damage.DamageType;
import net.minestom.server.entity.metadata.LivingEntityMeta; import net.minestom.server.entity.metadata.LivingEntityMeta;
import net.minestom.server.event.EventDispatcher; 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.network.player.PlayerConnection;
import net.minestom.server.scoreboard.Team; import net.minestom.server.scoreboard.Team;
import net.minestom.server.sound.SoundEvent; 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.block.BlockIterator;
import net.minestom.server.utils.time.Cooldown; import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit; 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! * Constructor which allows to specify an UUID. Only use if you know what you are doing!
*/ */
public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid) { public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid) {
this(entityType, uuid, new Position()); super(entityType, uuid);
initEquipments(); initEquipments();
} }
@ -98,20 +97,6 @@ public class LivingEntity extends Entity implements EquipmentHandler {
this(entityType, UUID.randomUUID()); 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() { private void initEquipments() {
this.mainHandItem = ItemStack.AIR; this.mainHandItem = ItemStack.AIR;
this.offHandItem = ItemStack.AIR; this.offHandItem = ItemStack.AIR;
@ -300,7 +285,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
setHealth(0); setHealth(0);
// Reset velocity // Reset velocity
velocity.zero(); this.velocity = Vec.ZERO;
// Remove passengers if any // Remove passengers if any
if (hasPassenger()) { if (hasPassenger()) {
@ -323,8 +308,8 @@ public class LivingEntity extends Entity implements EquipmentHandler {
/** /**
* Sets fire to this entity for a given duration. * Sets fire to this entity for a given duration.
* *
* @param duration duration of the effect * @param duration duration of the effect
* @param temporalUnit unit used to express the duration * @param temporalUnit unit used to express the duration
* @see #setOnFire(boolean) if you want it to be permanent without any event callback * @see #setOnFire(boolean) if you want it to be permanent without any event callback
*/ */
public void setFireForDuration(int duration, TemporalUnit temporalUnit) { 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 * @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) { public List<Point> getLineOfSight(int maxDistance) {
List<BlockPosition> blocks = new ArrayList<>(); List<Point> blocks = new ArrayList<>();
Iterator<BlockPosition> it = new BlockIterator(this, maxDistance); Iterator<Point> it = new BlockIterator(this, maxDistance);
while (it.hasNext()) { while (it.hasNext()) {
BlockPosition position = it.next(); final Point position = it.next();
if (!getInstance().getBlock(position).isAir()) blocks.add(position); if (!getInstance().getBlock(position).isAir()) blocks.add(position);
} }
return blocks; 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. * @return if the current entity has line of sight to the given one.
*/ */
public boolean hasLineOfSight(Entity entity) { public boolean hasLineOfSight(Entity entity) {
Vector start = getPosition().toVector().add(0D, getEyeHeight(), 0D); final var start = getPosition().asVec().add(0D, getEyeHeight(), 0D);
Vector end = entity.getPosition().toVector().add(0D, getEyeHeight(), 0D); final var end = entity.getPosition().asVec().add(0D, getEyeHeight(), 0D);
Vector direction = end.subtract(start); final var direction = end.sub(start);
int maxDistance = (int) Math.ceil(direction.length()); 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()) { while (it.hasNext()) {
Block block = getInstance().getBlock(it.next()); Block block = getInstance().getBlock(it.next());
if (!block.isAir() && !block.isLiquid()) { 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 * @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) { public Point getTargetBlockPosition(int maxDistance) {
Iterator<BlockPosition> it = new BlockIterator(this, maxDistance); Iterator<Point> it = new BlockIterator(this, maxDistance);
while (it.hasNext()) { while (it.hasNext()) {
BlockPosition position = it.next(); final Point position = it.next();
if (getInstance().getBlock(position) != Block.AIR) return position; if (!getInstance().getBlock(position).isAir()) return position;
} }
return null; return null;
} }
@ -804,8 +789,8 @@ public class LivingEntity extends Entity implements EquipmentHandler {
* Note: The strength is reduced based on knockback resistance * 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 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 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 z knockback on z axle, for default knockback use the following formula <pre>-cos(attacker.yaw * (pi/180))</pre>
*/ */
@Override @Override
public void takeKnockback(float strength, final double x, final double z) { 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.MinecraftServer;
import net.minestom.server.chat.ColoredText; import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage; 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.item.ItemStack;
import net.minestom.server.network.packet.server.play.EntityMetaDataPacket; 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.Direction;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.binary.Readable; import net.minestom.server.utils.binary.Readable;
import net.minestom.server.utils.binary.Writeable; import net.minestom.server.utils.binary.Writeable;
import net.minestom.server.utils.coordinate.Point;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBT; 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); 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 -> { return new Value<>(TYPE_ROTATION, value, writer -> {
writer.writeFloat((float) value.getX()); writer.writeFloat((float) value.x());
writer.writeFloat((float) value.getY()); writer.writeFloat((float) value.y());
writer.writeFloat((float) value.getZ()); writer.writeFloat((float) value.z());
}, reader -> new Vector(reader.readFloat(), reader.readFloat(), reader.readFloat())); }, reader -> new Vec(reader.readFloat(), reader.readFloat(), reader.readFloat()));
} }
public static Value<Point> Position(@NotNull Point value) { public static Value<Point> Position(@NotNull Point value) {
@ -339,7 +338,7 @@ public class Metadata {
case TYPE_STRING: case TYPE_STRING:
return (Value<T>) String(""); return (Value<T>) String("");
case TYPE_CHAT: case TYPE_CHAT:
return (Value<T>) Chat(ColoredText.of("")); return (Value<T>) Chat(Component.empty());
case TYPE_OPTCHAT: case TYPE_OPTCHAT:
return (Value<T>) OptChat((Component) null); return (Value<T>) OptChat((Component) null);
case TYPE_SLOT: case TYPE_SLOT:
@ -347,9 +346,9 @@ public class Metadata {
case TYPE_BOOLEAN: case TYPE_BOOLEAN:
return (Value<T>) Boolean(false); return (Value<T>) Boolean(false);
case TYPE_ROTATION: case TYPE_ROTATION:
return (Value<T>) Rotation(new Vector()); return (Value<T>) Rotation(Vec.ZERO);
case TYPE_POSITION: case TYPE_POSITION:
return (Value<T>) Position(new BlockPosition(0, 0, 0)); return (Value<T>) Position(Vec.ZERO);
case TYPE_OPTPOSITION: case TYPE_OPTPOSITION:
return (Value<T>) OptPosition(null); return (Value<T>) OptPosition(null);
case TYPE_DIRECTION: 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.collision.BoundingBox;
import net.minestom.server.command.CommandManager; import net.minestom.server.command.CommandManager;
import net.minestom.server.command.CommandSender; 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.effects.Effects;
import net.minestom.server.entity.damage.DamageType; import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.fakeplayer.FakePlayer; import net.minestom.server.entity.fakeplayer.FakePlayer;
@ -130,7 +133,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
private byte heldSlot; private byte heldSlot;
private Position respawnPoint; private Pos respawnPoint;
private int food; private int food;
private float foodSaturation; private float foodSaturation;
@ -179,7 +182,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
setBoundingBox(0.6f, 1.8f, 0.6f); setBoundingBox(0.6f, 1.8f, 0.6f);
setRespawnPoint(new Position(0, 0, 0)); setRespawnPoint(Pos.ZERO);
this.settings = new PlayerSettings(); this.settings = new PlayerSettings();
this.inventory = new PlayerInventory(this); 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 * @param spawnPosition the new position of the player
*/ */
@Override @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"); 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) // 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) || final boolean needWorldRefresh = !InstanceUtils.areLinked(this.instance, instance) ||
!spawnPosition.inSameChunk(this.position); !spawnPosition.inSameChunk(this.position);
@ -557,7 +559,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
* if the player is not in any instance). * if the player is not in any instance).
* *
* @param instance the new player instance * @param instance the new player instance
* @see #setInstance(Instance, Position) * @see #setInstance(Instance, Pos)
*/ */
@Override @Override
public void setInstance(@NotNull Instance instance) { public void setInstance(@NotNull Instance instance) {
@ -569,14 +571,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
* <p> * <p>
* Does add the player to {@code instance}, remove all viewable entities and call {@link PlayerSpawnEvent}. * Does add the player to {@code instance}, remove all viewable entities and call {@link PlayerSpawnEvent}.
* <p> * <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 spawnPosition the position to teleport the player
* @param firstSpawn true if this is the player first spawn * @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 * @param updateChunks true if chunks should be refreshed, false if the new instance shares the same
* chunks * 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) { boolean firstSpawn, boolean dimensionChange, boolean updateChunks) {
if (!firstSpawn) { if (!firstSpawn) {
// Player instance changed, clear current viewable collections // Player instance changed, clear current viewable collections
@ -699,17 +701,6 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
playerConnection.sendPacket(soundEffectPacket); 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). * 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); 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). * Plays a sound directly to the player (constant volume).
* *
@ -768,7 +748,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
@Override @Override
public void playSound(@NotNull Sound sound) { 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 @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) { public void playEffect(@NotNull Effects effect, int x, int y, int z, int data, boolean disableRelativeVolume) {
EffectPacket packet = new EffectPacket(); EffectPacket packet = new EffectPacket();
packet.effectId = effect.getId(); packet.effectId = effect.getId();
packet.position = new BlockPosition(x, y, z); packet.position = new Vec(x, y, z);
packet.data = data; packet.data = data;
packet.disableRelativeVolume = disableRelativeVolume; packet.disableRelativeVolume = disableRelativeVolume;
playerConnection.sendPacket(packet); playerConnection.sendPacket(packet);
@ -1294,14 +1274,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
facePosition(facePoint, entity.getPosition(), entity, targetPoint); 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) { @Nullable Entity entity, @Nullable FacePoint targetPoint) {
FacePlayerPacket facePlayerPacket = new FacePlayerPacket(); FacePlayerPacket facePlayerPacket = new FacePlayerPacket();
facePlayerPacket.entityFacePosition = facePoint == FacePoint.EYE ? facePlayerPacket.entityFacePosition = facePoint == FacePoint.EYE ?
FacePlayerPacket.FacePosition.EYES : FacePlayerPacket.FacePosition.FEET; FacePlayerPacket.FacePosition.EYES : FacePlayerPacket.FacePosition.FEET;
facePlayerPacket.targetX = targetPosition.getX(); facePlayerPacket.targetX = targetPosition.x();
facePlayerPacket.targetY = targetPosition.getY(); facePlayerPacket.targetY = targetPosition.y();
facePlayerPacket.targetZ = targetPosition.getZ(); facePlayerPacket.targetZ = targetPosition.z();
if (entity != null) { if (entity != null) {
facePlayerPacket.entityId = entity.getEntityId(); facePlayerPacket.entityId = entity.getEntityId();
facePlayerPacket.entityFacePosition = targetPoint == FacePoint.EYE ? facePlayerPacket.entityFacePosition = targetPoint == FacePoint.EYE ?
@ -1329,13 +1309,12 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
/** /**
* Used to retrieve the default spawn point. * Used to retrieve the default spawn point.
* <p> * <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 * @return a copy of the default respawn point
*/ */
@NotNull public @NotNull Pos getRespawnPoint() {
public Position getRespawnPoint() { return respawnPoint;
return respawnPoint.clone();
} }
/** /**
@ -1343,7 +1322,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
* *
* @param respawnPoint the player respawn point * @param respawnPoint the player respawn point
*/ */
public void setRespawnPoint(@NotNull Position respawnPoint) { public void setRespawnPoint(@NotNull Pos respawnPoint) {
this.respawnPoint = respawnPoint; this.respawnPoint = respawnPoint;
} }
@ -1365,8 +1344,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
{ {
// Send new chunks // Send new chunks
final BlockPosition pos = position.toBlockPosition(); final Chunk chunk = instance.getChunkAt(position);
final Chunk chunk = instance.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
Check.notNull(chunk, "Tried to interact with an unloaded chunk."); Check.notNull(chunk, "Tried to interact with an unloaded chunk.");
refreshVisibleChunks(chunk); refreshVisibleChunks(chunk);
} }
@ -1903,7 +1881,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
protected void synchronizePosition(boolean includeSelf) { protected void synchronizePosition(boolean includeSelf) {
if (includeSelf) { if (includeSelf) {
final PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket(); final PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket();
positionAndLookPacket.position = position.clone(); positionAndLookPacket.position = position;
positionAndLookPacket.flags = 0x00; positionAndLookPacket.flags = 0x00;
positionAndLookPacket.teleportId = teleportId.incrementAndGet(); positionAndLookPacket.teleportId = teleportId.incrementAndGet();
playerConnection.sendPacket(positionAndLookPacket); playerConnection.sendPacket(positionAndLookPacket);
@ -2324,7 +2302,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket(); EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
entityHeadLookPacket.entityId = getEntityId(); entityHeadLookPacket.entityId = getEntityId();
entityHeadLookPacket.yaw = position.getYaw(); entityHeadLookPacket.yaw = position.yaw();
connection.sendPacket(entityHeadLookPacket); 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.Entity;
import net.minestom.server.entity.EntityCreature; import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityProjectile;
import net.minestom.server.entity.EntityType; import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.entity.pathfinding.Navigator; 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.Cooldown;
import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.utils.validate.Check; 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 (!Cooldown.hasCooldown(time, this.lastAttack, this.rangedDelay)) {
if (this.entityCreature.hasLineOfSight(target)) { if (this.entityCreature.hasLineOfSight(target)) {
// If target is on line of entity sight, ranged attack can be performed // 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; Function<Entity, EntityProjectile> projectileGenerator = this.projectileGenerator;
if (projectileGenerator == null) { if (projectileGenerator == null) {
@ -193,7 +192,7 @@ public class CombinedAttackGoal extends GoalSelector {
} }
} }
Navigator navigator = this.entityCreature.getNavigator(); 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 we don't want to come close and we're already within desirable range, no movement is needed.
if (!comeClose && distanceSquared <= this.desirableRangeSquared) { if (!comeClose && distanceSquared <= this.desirableRangeSquared) {
if (pathPosition != null) { if (pathPosition != null) {
@ -202,8 +201,8 @@ public class CombinedAttackGoal extends GoalSelector {
return; return;
} }
// Otherwise going to the target. // Otherwise going to the target.
Position targetPosition = target.getPosition(); final var targetPosition = target.getPosition();
if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) { if (pathPosition == null || !pathPosition.samePoint(targetPosition)) {
if (this.cooldown.isReady(time)) { if (this.cooldown.isReady(time)) {
this.cooldown.refreshLastUpdate(time); this.cooldown.refreshLastUpdate(time);
navigator.setPathTo(targetPosition); 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.EntityCreature;
import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.entity.pathfinding.Navigator; import net.minestom.server.entity.pathfinding.Navigator;
import net.minestom.server.utils.MathUtils; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.time.Duration; import java.time.Duration;
@ -15,14 +14,13 @@ public class FollowTargetGoal extends GoalSelector {
private final Duration pathDuration; private final Duration pathDuration;
private long lastUpdateTime = 0; private long lastUpdateTime = 0;
private boolean forceEnd = false; private boolean forceEnd = false;
private Position lastTargetPos; private Point lastTargetPos;
/** /**
* Creates a follow target goal object. * Creates a follow target goal object.
* *
* @param entityCreature the entity * @param entityCreature the entity
* @param pathUpdateOption the time between each path update (to check if the target moved) * @param pathUpdateOption the time between each path update (to check if the target moved)
*
* @deprecated Replaced by {@link #FollowTargetGoal(EntityCreature, Duration)} * @deprecated Replaced by {@link #FollowTargetGoal(EntityCreature, Duration)}
*/ */
@SuppressWarnings("removal") @SuppressWarnings("removal")
@ -34,8 +32,8 @@ public class FollowTargetGoal extends GoalSelector {
/** /**
* Creates a follow target goal object. * Creates a follow target goal object.
* *
* @param entityCreature the entity * @param entityCreature the entity
* @param pathDuration the time between each path update (to check if the target moved) * @param pathDuration the time between each path update (to check if the target moved)
*/ */
public FollowTargetGoal(@NotNull EntityCreature entityCreature, @NotNull Duration pathDuration) { public FollowTargetGoal(@NotNull EntityCreature entityCreature, @NotNull Duration pathDuration) {
super(entityCreature); super(entityCreature);
@ -45,7 +43,7 @@ public class FollowTargetGoal extends GoalSelector {
@Override @Override
public boolean shouldStart() { public boolean shouldStart() {
return entityCreature.getTarget() != null && return entityCreature.getTarget() != null &&
getDistance(entityCreature.getTarget().getPosition(), entityCreature.getPosition()) >= 2; entityCreature.getTarget().getPosition().distance(entityCreature.getPosition()) >= 2;
} }
@Override @Override
@ -54,19 +52,18 @@ public class FollowTargetGoal extends GoalSelector {
forceEnd = false; forceEnd = false;
lastTargetPos = null; lastTargetPos = null;
final Entity target = entityCreature.getTarget(); final Entity target = entityCreature.getTarget();
if (target != null) { if (target != null) {
Navigator navigator = entityCreature.getNavigator(); Navigator navigator = entityCreature.getNavigator();
lastTargetPos = target.getPosition().clone(); lastTargetPos = target.getPosition();
if (getDistance(lastTargetPos, entityCreature.getPosition()) < 2) { if (lastTargetPos.distance(entityCreature.getPosition()) < 2) {
forceEnd = true; forceEnd = true;
navigator.setPathTo(null); navigator.setPathTo(null);
return; return;
} }
if (navigator.getPathPosition() == null || if (navigator.getPathPosition() == null ||
(!navigator.getPathPosition().isSimilar(lastTargetPos))) { (!navigator.getPathPosition().samePoint(lastTargetPos))) {
navigator.setPathTo(lastTargetPos); navigator.setPathTo(lastTargetPos);
} else { } else {
forceEnd = true; forceEnd = true;
@ -83,28 +80,24 @@ public class FollowTargetGoal extends GoalSelector {
pathDuration.toMillis() + lastUpdateTime > time) { pathDuration.toMillis() + lastUpdateTime > time) {
return; return;
} }
Position targetPos = entityCreature.getTarget() != null ? entityCreature.getTarget().getPosition() : null; final var targetPos = entityCreature.getTarget() != null ? entityCreature.getTarget().getPosition() : null;
if (targetPos != null && !targetPos.equals(lastTargetPos)) { if (targetPos != null && !targetPos.samePoint(lastTargetPos)) {
lastUpdateTime = time; this.lastUpdateTime = time;
lastTargetPos.copy(lastTargetPos); this.lastTargetPos = targetPos;
entityCreature.getNavigator().setPathTo(targetPos); this.entityCreature.getNavigator().setPathTo(targetPos);
} }
} }
@Override @Override
public boolean shouldEnd() { public boolean shouldEnd() {
final Entity target = entityCreature.getTarget();
return forceEnd || return forceEnd ||
entityCreature.getTarget() == null || target == null ||
getDistance(entityCreature.getTarget().getPosition(), entityCreature.getPosition()) < 2; target.getPosition().distance(entityCreature.getPosition()) < 2;
} }
@Override @Override
public void end() { public void end() {
entityCreature.getNavigator().setPathTo(null); 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.GoalSelector;
import net.minestom.server.entity.ai.TargetSelector; import net.minestom.server.entity.ai.TargetSelector;
import net.minestom.server.entity.pathfinding.Navigator; 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.Cooldown;
import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -61,7 +61,7 @@ public class MeleeAttackGoal extends GoalSelector {
@Override @Override
public void start() { public void start() {
final Position targetPosition = this.cachedTarget.getPosition(); final Point targetPosition = this.cachedTarget.getPosition();
entityCreature.getNavigator().setPathTo(targetPosition); entityCreature.getNavigator().setPathTo(targetPosition);
} }
@ -90,9 +90,9 @@ public class MeleeAttackGoal extends GoalSelector {
// Move toward the target entity // Move toward the target entity
Navigator navigator = entityCreature.getNavigator(); Navigator navigator = entityCreature.getNavigator();
final Position pathPosition = navigator.getPathPosition(); final var pathPosition = navigator.getPathPosition();
final Position targetPosition = target.getPosition(); final var targetPosition = target.getPosition();
if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) { if (pathPosition == null || !pathPosition.samePoint(targetPosition)) {
if (this.cooldown.isReady(time)) { if (this.cooldown.isReady(time)) {
this.cooldown.refreshLastUpdate(time); this.cooldown.refreshLastUpdate(time);
navigator.setPathTo(targetPosition); 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.EntityCreature;
import net.minestom.server.entity.ai.GoalSelector; 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 org.jetbrains.annotations.NotNull;
import java.util.Random; import java.util.Random;
@ -13,20 +13,20 @@ public class RandomLookAroundGoal extends GoalSelector {
private static final Random RANDOM = new Random(); private static final Random RANDOM = new Random();
private final int chancePerTick; private final int chancePerTick;
private final Supplier<Integer> minimalLookTimeSupplier; private final Supplier<Integer> minimalLookTimeSupplier;
private final Function<EntityCreature, Vector> randomDirectionFunction; private final Function<EntityCreature, Vec> randomDirectionFunction;
private Vector lookDirection; private Vec lookDirection;
private int lookTime = 0; private int lookTime = 0;
public RandomLookAroundGoal(EntityCreature entityCreature, int chancePerTick) { public RandomLookAroundGoal(EntityCreature entityCreature, int chancePerTick) {
this(entityCreature, 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. // Look in one direction for at most 40 ticks and at minimum 20 ticks.
() -> 20 + RANDOM.nextInt(20), () -> 20 + RANDOM.nextInt(20),
// Look at a random block // Look at a random block
(creature) -> { (creature) -> {
final double n = Math.PI * 2 * RANDOM.nextDouble(); final double n = Math.PI * 2 * RANDOM.nextDouble();
return new Vector( return new Vec(
(float) Math.cos(n), (float) Math.cos(n),
0, 0,
(float) Math.sin(n) (float) Math.sin(n)
@ -44,8 +44,7 @@ public class RandomLookAroundGoal extends GoalSelector {
EntityCreature entityCreature, EntityCreature entityCreature,
int chancePerTick, int chancePerTick,
@NotNull Supplier<Integer> minimalLookTimeSupplier, @NotNull Supplier<Integer> minimalLookTimeSupplier,
@NotNull Function<EntityCreature, Vector> randomDirectionFunction @NotNull Function<EntityCreature, Vec> randomDirectionFunction) {
) {
super(entityCreature); super(entityCreature);
this.chancePerTick = chancePerTick; this.chancePerTick = chancePerTick;
this.minimalLookTimeSupplier = minimalLookTimeSupplier; this.minimalLookTimeSupplier = minimalLookTimeSupplier;
@ -69,7 +68,7 @@ public class RandomLookAroundGoal extends GoalSelector {
@Override @Override
public void tick(long time) { public void tick(long time) {
--lookTime; --lookTime;
entityCreature.setView(entityCreature.getPosition().clone().setDirection(lookDirection)); entityCreature.refreshPosition(entityCreature.getPosition().withDirection(lookDirection));
} }
@Override @Override
@ -79,6 +78,5 @@ public class RandomLookAroundGoal extends GoalSelector {
@Override @Override
public void end() { 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.EntityCreature;
import net.minestom.server.entity.ai.GoalSelector; 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 org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
@ -14,14 +14,13 @@ public class RandomStrollGoal extends GoalSelector {
private static final long DELAY = 2500; private static final long DELAY = 2500;
private final int radius; private final int radius;
private final List<Position> closePositions; private final List<Vec> closePositions;
private long lastStroll; private long lastStroll;
public RandomStrollGoal(@NotNull EntityCreature entityCreature, int radius) { public RandomStrollGoal(@NotNull EntityCreature entityCreature, int radius) {
super(entityCreature); super(entityCreature);
this.radius = radius; this.radius = radius;
this.closePositions = getNearbyBlocks(radius); this.closePositions = getNearbyBlocks(radius);
} }
@ -33,20 +32,17 @@ public class RandomStrollGoal extends GoalSelector {
@Override @Override
public void start() { public void start() {
Collections.shuffle(closePositions); Collections.shuffle(closePositions);
for (var position : closePositions) {
for (Position position : closePositions) { final var target = entityCreature.getPosition().add(position);
final Position target = position.clone().add(entityCreature.getPosition());
final boolean result = entityCreature.getNavigator().setPathTo(target); final boolean result = entityCreature.getNavigator().setPathTo(target);
if (result) { if (result) {
break; break;
} }
} }
} }
@Override @Override
public void tick(long time) { public void tick(long time) {
} }
@Override @Override
@ -64,17 +60,15 @@ public class RandomStrollGoal extends GoalSelector {
} }
@NotNull @NotNull
private List<Position> getNearbyBlocks(int radius) { private List<Vec> getNearbyBlocks(int radius) {
List<Position> blocks = new ArrayList<>(); List<Vec> blocks = new ArrayList<>();
for (int x = -radius; x <= radius; x++) { for (int x = -radius; x <= radius; x++) {
for (int y = -radius; y <= radius; y++) { for (int y = -radius; y <= radius; y++) {
for (int z = -radius; z <= radius; z++) { for (int z = -radius; z <= radius; z++) {
final Position position = new Position(x, y, z); blocks.add(new Vec(x, y, z));
blocks.add(position);
} }
} }
} }
return blocks; return blocks;
} }
} }

View File

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

View File

@ -1,5 +1,6 @@
package net.minestom.server.entity.fakeplayer; package net.minestom.server.entity.fakeplayer;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.instance.block.BlockFace; 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.KeepAlivePacket;
import net.minestom.server.network.packet.server.play.PlayerPositionAndLookPacket; import net.minestom.server.network.packet.server.play.PlayerPositionAndLookPacket;
import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.MathUtils; import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.inventory.PlayerInventoryUtils; import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import net.minestom.server.utils.validate.Check; 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 blockPosition The position of the block to be excavated.
* @param blockFace From where the block is struck. * @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(); ClientPlayerDiggingPacket playerDiggingPacket = new ClientPlayerDiggingPacket();
playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.STARTED_DIGGING; playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.STARTED_DIGGING;
playerDiggingPacket.blockPosition = blockPosition; playerDiggingPacket.blockPosition = blockPosition;
@ -193,7 +193,7 @@ public class FakePlayerController {
* @param blockPosition The position of the block to be excavated. * @param blockPosition The position of the block to be excavated.
* @param blockFace From where the block is struck. * @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(); ClientPlayerDiggingPacket playerDiggingPacket = new ClientPlayerDiggingPacket();
playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING; playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.CANCELLED_DIGGING;
playerDiggingPacket.blockPosition = blockPosition; playerDiggingPacket.blockPosition = blockPosition;
@ -207,7 +207,7 @@ public class FakePlayerController {
* @param blockPosition The position of the block to be excavated. * @param blockPosition The position of the block to be excavated.
* @param blockFace From where the block is struck. * @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(); ClientPlayerDiggingPacket playerDiggingPacket = new ClientPlayerDiggingPacket();
playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.FINISHED_DIGGING; playerDiggingPacket.status = ClientPlayerDiggingPacket.Status.FINISHED_DIGGING;
playerDiggingPacket.blockPosition = blockPosition; 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.Player;
import net.minestom.server.entity.metadata.other.ArmorStandMeta; import net.minestom.server.entity.metadata.other.ArmorStandMeta;
import net.minestom.server.instance.Instance; 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 net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -25,7 +25,7 @@ public class Hologram implements Viewable {
private final Entity entity; private final Entity entity;
private final float yOffset; private final float yOffset;
private Position position; private Pos position;
private Component text; private Component text;
private boolean removed; private boolean removed;
@ -36,35 +36,8 @@ public class Hologram implements Viewable {
* @param instance The instance where the hologram should be spawned. * @param instance The instance where the hologram should be spawned.
* @param spawnPosition The spawn position of this hologram. * @param spawnPosition The spawn position of this hologram.
* @param text The text 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, Pos spawnPosition, Component text) {
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) {
this(instance, spawnPosition, text, true); this(instance, spawnPosition, text, true);
} }
@ -76,7 +49,7 @@ public class Hologram implements Viewable {
* @param text The text of this hologram. * @param text The text of this hologram.
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}. * @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); this(instance, spawnPosition, text, autoViewable, false);
} }
@ -88,7 +61,7 @@ public class Hologram implements Viewable {
* @param text The text of this hologram. * @param text The text of this hologram.
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}. * @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); this.entity = new Entity(EntityType.ARMOR_STAND);
ArmorStandMeta armorStandMeta = (ArmorStandMeta) entity.getEntityMeta(); ArmorStandMeta armorStandMeta = (ArmorStandMeta) entity.getEntityMeta();
@ -109,7 +82,7 @@ public class Hologram implements Viewable {
armorStandMeta.setNotifyAboutChanges(true); 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.entity.setAutoViewable(autoViewable);
this.position = spawnPosition; this.position = spawnPosition;
@ -121,7 +94,7 @@ public class Hologram implements Viewable {
* *
* @return the hologram's position * @return the hologram's position
*/ */
public Position getPosition() { public Pos getPosition() {
return position; return position;
} }
@ -130,11 +103,10 @@ public class Hologram implements Viewable {
* *
* @param position the new hologram's position * @param position the new hologram's position
*/ */
public void setPosition(Position position) { public void setPosition(Pos position) {
checkRemoved(); checkRemoved();
position.add(0, this.yOffset, 0); this.position = position.add(0, this.yOffset, 0);
this.position = position; this.entity.teleport(this.position);
this.entity.teleport(position);
} }
/** /**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +1,9 @@
package net.minestom.server.entity.metadata.water; 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.Entity;
import net.minestom.server.entity.Metadata; 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.NotNull;
public class DolphinMeta extends WaterAnimalMeta { public class DolphinMeta extends WaterAnimalMeta {
@ -15,11 +15,11 @@ public class DolphinMeta extends WaterAnimalMeta {
} }
@NotNull @NotNull
public BlockPosition getTreasurePosition() { public Point getTreasurePosition() {
return super.metadata.getIndex(OFFSET, new BlockPosition(0, 0, 0)); 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)); 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.PathOptions;
import com.extollit.gaming.ai.path.model.IPath; import com.extollit.gaming.ai.path.model.IPath;
import net.minestom.server.collision.CollisionUtils; 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.Entity;
import net.minestom.server.entity.LivingEntity; import net.minestom.server.entity.LivingEntity;
import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.minestom.server.instance.WorldBorder; 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.chunk.ChunkUtils;
import net.minestom.server.utils.position.PositionUtils; import net.minestom.server.utils.position.PositionUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -26,7 +27,7 @@ public class Navigator {
private final PFPathingEntity pathingEntity; private final PFPathingEntity pathingEntity;
private HydrazinePathFinder pathFinder; private HydrazinePathFinder pathFinder;
private IPath path; private IPath path;
private Position pathPosition; private Point pathPosition;
private final Entity entity; private final Entity entity;
@ -43,17 +44,16 @@ public class Navigator {
* @param direction the targeted position * @param direction the targeted position
* @param speed define how far the entity will move * @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 targetX = direction.x();
final double currentY = position.getY(); final double targetY = direction.y();
final double currentZ = position.getZ(); final double targetZ = direction.z();
final double targetX = direction.getX();
final double targetY = direction.getY();
final double targetZ = direction.getZ();
final double dx = targetX - currentX; final double dx = targetX - currentX;
final double dy = targetY - currentY; final double dy = targetY - currentY;
@ -71,24 +71,17 @@ public class Navigator {
final double speedZ = Math.sin(radians) * speed; final double speedZ = Math.sin(radians) * speed;
// Update 'position' view // Update 'position' view
PositionUtils.lookAlong(position, dx, direction.getY(), dz); final var view = PositionUtils.lookAlong(position, dx, direction.y(), dz);
entity.setView(view.yaw(), view.pitch());
Position newPosition = new Position();
Vector newVelocityOut = new Vector();
// Prevent ghosting // Prevent ghosting
CollisionUtils.handlePhysics(entity, final var physicsResult = CollisionUtils.handlePhysics(entity, new Vec(speedX, speedY, speedZ));
new Vector(speedX, speedY, speedZ), entity.refreshPosition(physicsResult.newPosition());
newPosition, newVelocityOut);
// Will move the entity during Entity#tick
position.copyCoordinates(newPosition);
} }
public void jump(float height) { public void jump(float height) {
// FIXME magic value // FIXME magic value
final Vector velocity = new Vector(0, height * 2.5f, 0); this.entity.setVelocity(new Vec(0, height * 2.5f, 0));
this.entity.setVelocity(velocity);
} }
/** /**
@ -99,13 +92,13 @@ public class Navigator {
* The position is cloned, if you want the entity to continually follow this position object * 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. * 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, * @param bestEffort whether to use the best-effort algorithm to the destination,
* if false then this method is more likely to return immediately * if false then this method is more likely to return immediately
* @return true if a path has been found * @return true if a path has been found
*/ */
public synchronized boolean setPathTo(@Nullable Position position, boolean bestEffort) { public synchronized boolean setPathTo(@Nullable Point point, boolean bestEffort) {
if (position != null && pathPosition != null && position.isSimilar(pathPosition)) { if (point != null && pathPosition != null && point.samePoint(pathPosition)) {
// Tried to set path to the same target position // Tried to set path to the same target position
return false; return false;
} }
@ -118,7 +111,7 @@ public class Navigator {
} }
pathFinder.reset(); pathFinder.reset();
if (position == null) { if (point == null) {
return false; return false;
} }
@ -129,38 +122,36 @@ public class Navigator {
// Can't path outside of the world border // Can't path outside of the world border
final WorldBorder worldBorder = instance.getWorldBorder(); final WorldBorder worldBorder = instance.getWorldBorder();
if (!worldBorder.isInside(position)) { if (!worldBorder.isInside(point)) {
return false; return false;
} }
// Can't path in an unloaded chunk // Can't path in an unloaded chunk
final Chunk chunk = instance.getChunkAt(position); final Chunk chunk = instance.getChunkAt(point);
if (!ChunkUtils.isLoaded(chunk)) { if (!ChunkUtils.isLoaded(chunk)) {
return false; return false;
} }
final Position targetPosition = position.clone();
final PathOptions pathOptions = new PathOptions() final PathOptions pathOptions = new PathOptions()
.targetingStrategy(bestEffort ? PathOptions.TargetingStrategy.gravitySnap : .targetingStrategy(bestEffort ? PathOptions.TargetingStrategy.gravitySnap :
PathOptions.TargetingStrategy.none); PathOptions.TargetingStrategy.none);
final IPath path = pathFinder.initiatePathTo( final IPath path = pathFinder.initiatePathTo(
targetPosition.getX(), point.x(),
targetPosition.getY(), point.y(),
targetPosition.getZ(), point.z(),
pathOptions); pathOptions);
this.path = path; this.path = path;
final boolean success = path != null; final boolean success = path != null;
this.pathPosition = success ? targetPosition : null; this.pathPosition = success ? point : null;
return success; 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); return setPathTo(position, true);
} }
@ -174,7 +165,7 @@ public class Navigator {
this.path = path; this.path = path;
if (path != null) { if (path != null) {
final Position targetPosition = pathingEntity.getTargetPosition(); final Point targetPosition = pathingEntity.getTargetPosition();
if (targetPosition != null) { if (targetPosition != null) {
moveTowards(targetPosition, speed); moveTowards(targetPosition, speed);
} }
@ -220,8 +211,7 @@ public class Navigator {
* *
* @return the target pathfinder position, null if there is no one * @return the target pathfinder position, null if there is no one
*/ */
@Nullable public @Nullable Point getPathPosition() {
public Position getPathPosition() {
return pathPosition; return pathPosition;
} }
@ -229,10 +219,10 @@ public class Navigator {
* Changes the position this element is trying to reach. * Changes the position this element is trying to reach.
* *
* @param pathPosition the new current path position * @param pathPosition the new current path position
* @deprecated Please use {@link #setPathTo(Position)} * @deprecated Please use {@link #setPathTo(Point)}
*/ */
@Deprecated @Deprecated
public void setPathPosition(@Nullable Position pathPosition) { public void setPathPosition(@Nullable Point pathPosition) {
this.pathPosition = 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.gaming.ai.path.model.Passibility;
import com.extollit.linalg.immutable.Vec3d; import com.extollit.linalg.immutable.Vec3d;
import net.minestom.server.attribute.Attribute; 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.Entity;
import net.minestom.server.entity.LivingEntity; import net.minestom.server.entity.LivingEntity;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class PFPathingEntity implements IPathingEntity { public class PFPathingEntity implements IPathingEntity {
@ -16,7 +17,7 @@ public class PFPathingEntity implements IPathingEntity {
private final Entity entity; private final Entity entity;
private float searchRange; private float searchRange;
private Position targetPosition; private Point targetPosition;
// Capacities // Capacities
private boolean fireResistant; private boolean fireResistant;
@ -36,7 +37,7 @@ public class PFPathingEntity implements IPathingEntity {
this.searchRange = getAttributeValue(Attribute.FOLLOW_RANGE); this.searchRange = getAttributeValue(Attribute.FOLLOW_RANGE);
} }
public Position getTargetPosition() { public Point getTargetPosition() {
return targetPosition; return targetPosition;
} }
@ -193,18 +194,17 @@ public class PFPathingEntity implements IPathingEntity {
@Override @Override
public void moveTo(Vec3d position, Passibility passibility, Gravitation gravitation) { public void moveTo(Vec3d position, Passibility passibility, Gravitation gravitation) {
this.targetPosition = new Position(position.x, position.y, position.z); this.targetPosition = new Vec(position.x, position.y, position.z);
final double entityY = entity.getPosition().y();
final double entityY = entity.getPosition().getY(); if (entityY < targetPosition.y()) {
if (entityY < targetPosition.getY()) {
this.navigator.jump(1); this.navigator.jump(1);
} }
} }
@Override @Override
public Vec3d coordinates() { public Vec3d coordinates() {
final Position position = entity.getPosition(); final var position = entity.getPosition();
return new Vec3d(position.getX(), position.getY(), position.getZ()); return new Vec3d(position.x(), position.y(), position.z());
} }
@Override @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.CancellableEvent;
import net.minestom.server.event.trait.EntityEvent; import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.utils.Position; import net.minestom.server.utils.Position;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull; 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 { public class EntityShootEvent implements EntityEvent, CancellableEvent {
private final Entity entity; private final Entity entity;
private final Entity projectile; private final Entity projectile;
private final Position to; private final Point to;
private double power; private double power;
private double spread; private double spread;
private boolean cancelled; 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.entity = entity;
this.projectile = projectile; this.projectile = projectile;
this.to = to; this.to = to;
@ -42,7 +43,7 @@ public class EntityShootEvent implements EntityEvent, CancellableEvent {
* *
* @return the position projectile was shot to. * @return the position projectile was shot to.
*/ */
public Position getTo() { public Point getTo() {
return this.to; 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.entity.Entity;
import net.minestom.server.event.trait.CancellableEvent; import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.EntityEvent; import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.utils.Vector; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; 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 { public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
private final Entity entity; private final Entity entity;
private Vector velocity; private Vec velocity;
private boolean cancelled; private boolean cancelled;
public EntityVelocityEvent(@NotNull Entity entity, @NotNull Vector velocity) { public EntityVelocityEvent(@NotNull Entity entity, @NotNull Vec velocity) {
this.entity = entity; this.entity = entity;
this.velocity = velocity; this.velocity = velocity;
} }
@ -26,9 +26,8 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
* *
* @return the entity * @return the entity
*/ */
@NotNull
@Override @Override
public Entity getEntity() { public @NotNull Entity getEntity() {
return entity; return entity;
} }
@ -37,8 +36,7 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
* *
* @return the velocity * @return the velocity
*/ */
@NotNull public @NotNull Vec getVelocity() {
public Vector getVelocity() {
return velocity; return velocity;
} }
@ -47,7 +45,7 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
* *
* @param velocity the new velocity * @param velocity the new velocity
*/ */
public void setVelocity(@NotNull Vector velocity) { public void setVelocity(@NotNull Vec velocity) {
this.velocity = 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.CancellableEvent;
import net.minestom.server.event.trait.PlayerEvent; import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block; 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; import org.jetbrains.annotations.NotNull;
public class PlayerBlockBreakEvent implements PlayerEvent, BlockEvent, CancellableEvent { 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.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace; import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.BlockPosition; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Point;
import org.jetbrains.annotations.NotNull; 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.CancellableEvent;
import net.minestom.server.event.trait.PlayerEvent; import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.BlockPosition; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Point;
import org.jetbrains.annotations.NotNull; 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.entity.Player;
import net.minestom.server.event.trait.CancellableEvent; import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.PlayerEvent; import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.utils.Position; import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@ -12,11 +12,11 @@ import org.jetbrains.annotations.NotNull;
public class PlayerMoveEvent implements PlayerEvent, CancellableEvent { public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
private final Player player; private final Player player;
private Position newPosition; private Pos newPosition;
private boolean cancelled; private boolean cancelled;
public PlayerMoveEvent(@NotNull Player player, @NotNull Position newPosition) { public PlayerMoveEvent(@NotNull Player player, @NotNull Pos newPosition) {
this.player = player; this.player = player;
this.newPosition = newPosition; this.newPosition = newPosition;
} }
@ -26,8 +26,7 @@ public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
* *
* @return the new position * @return the new position
*/ */
@NotNull public @NotNull Pos getNewPosition() {
public Position getNewPosition() {
return newPosition; return newPosition;
} }
@ -36,7 +35,7 @@ public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
* *
* @param newPosition the new target position * @param newPosition the new target position
*/ */
public void setNewPosition(@NotNull Position newPosition) { public void setNewPosition(@NotNull Pos newPosition) {
this.newPosition = newPosition; this.newPosition = newPosition;
} }

View File

@ -1,9 +1,8 @@
package net.minestom.server.event.player; package net.minestom.server.event.player;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.Event;
import net.minestom.server.event.trait.PlayerEvent; import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.utils.Position; import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@ -13,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
public class PlayerRespawnEvent implements PlayerEvent { public class PlayerRespawnEvent implements PlayerEvent {
private final Player player; private final Player player;
private Position respawnPosition; private Pos respawnPosition;
public PlayerRespawnEvent(@NotNull Player player) { public PlayerRespawnEvent(@NotNull Player player) {
this.player = player; this.player = player;
@ -27,8 +26,7 @@ public class PlayerRespawnEvent implements PlayerEvent {
* *
* @return the respawn position * @return the respawn position
*/ */
@NotNull public @NotNull Pos getRespawnPosition() {
public Position getRespawnPosition() {
return respawnPosition; return respawnPosition;
} }
@ -37,7 +35,7 @@ public class PlayerRespawnEvent implements PlayerEvent {
* *
* @param respawnPosition the new respawn position * @param respawnPosition the new respawn position
*/ */
public void setRespawnPosition(@NotNull Position respawnPosition) { public void setRespawnPosition(@NotNull Pos respawnPosition) {
this.respawnPosition = 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.CancellableEvent;
import net.minestom.server.event.trait.PlayerEvent; import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block; 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; 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.event.trait.PlayerEvent;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.Direction; import net.minestom.server.utils.Direction;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull; 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.Tickable;
import net.minestom.server.Viewable; 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.Data;
import net.minestom.server.data.DataContainer; import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.Player; 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.ChunkDataPacket;
import net.minestom.server.network.packet.server.play.UpdateLightPacket; import net.minestom.server.network.packet.server.play.UpdateLightPacket;
import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.ArrayUtils;
import net.minestom.server.tag.Tag; import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagHandler; 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.Position;
import net.minestom.server.utils.chunk.ChunkSupplier; import net.minestom.server.utils.chunk.ChunkSupplier;
import net.minestom.server.world.biomes.Biome; 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 * @return the position of this chunk
*/ */
@NotNull public @NotNull Point toPosition() {
public Position toPosition() { return new Vec(CHUNK_SIZE_Z * getChunkX(), 0, CHUNK_SIZE_Z * getChunkZ());
return new Position(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 com.extollit.gaming.ai.path.model.ColumnarOcclusionFieldList;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.pathfinding.PFBlock; import net.minestom.server.entity.pathfinding.PFBlock;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockHandler; import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.network.packet.server.play.ChunkDataPacket; 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.chunk.ChunkUtils;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.validate.Check;
import net.minestom.server.world.biomes.Biome; import net.minestom.server.world.biomes.Biome;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -17,7 +15,6 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.util.Map; import java.util.Map;
import java.time.Duration;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
@ -99,7 +96,7 @@ public class DynamicChunk extends Chunk {
final int x = ChunkUtils.blockIndexToChunkPositionX(index); final int x = ChunkUtils.blockIndexToChunkPositionX(index);
final int y = ChunkUtils.blockIndexToChunkPositionY(index); final int y = ChunkUtils.blockIndexToChunkPositionY(index);
final int z = ChunkUtils.blockIndexToChunkPositionZ(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); final Block block = getBlock(blockPosition);
entry.getValue().tick(new BlockHandler.Tick(block, instance, blockPosition)); entry.getValue().tick(new BlockHandler.Tick(block, instance, blockPosition));

View File

@ -1,8 +1,8 @@
package net.minestom.server.instance; package net.minestom.server.instance;
import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.network.packet.server.play.ExplosionPacket; import net.minestom.server.network.packet.server.play.ExplosionPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.PacketUtils; import net.minestom.server.utils.PacketUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -48,7 +48,7 @@ public abstract class Explosion {
* @param instance instance to perform this explosion in * @param instance instance to perform this explosion in
* @return list of blocks that will be broken. * @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 * Performs the explosion and send the corresponding packet
@ -56,7 +56,7 @@ public abstract class Explosion {
* @param instance instance to perform this explosion in * @param instance instance to perform this explosion in
*/ */
public void apply(@NotNull Instance instance) { public void apply(@NotNull Instance instance) {
List<BlockPosition> blocks = prepare(instance); List<Point> blocks = prepare(instance);
ExplosionPacket packet = new ExplosionPacket(); ExplosionPacket packet = new ExplosionPacket();
packet.x = getCenterX(); packet.x = getCenterX();
packet.y = getCenterY(); packet.y = getCenterY();
@ -68,11 +68,11 @@ public abstract class Explosion {
packet.records = new byte[3 * blocks.size()]; packet.records = new byte[3 * blocks.size()];
for (int i = 0; i < blocks.size(); i++) { 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); instance.setBlock(pos, Block.AIR);
final byte x = (byte) (pos.getX() - Math.floor(getCenterX())); final byte x = (byte) (pos.x() - Math.floor(getCenterX()));
final byte y = (byte) (pos.getY() - Math.floor(getCenterY())); final byte y = (byte) (pos.y() - Math.floor(getCenterY()));
final byte z = (byte) (pos.getZ() - Math.floor(getCenterZ())); final byte z = (byte) (pos.z() - Math.floor(getCenterZ()));
packet.records[i * 3 + 0] = x; packet.records[i * 3 + 0] = x;
packet.records[i * 3 + 1] = y; packet.records[i * 3 + 1] = y;
packet.records[i * 3 + 2] = z; 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. * 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. * 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 instance the instance in which the explosion occurs
* @param blocks the block positions returned by prepare * @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.Tickable;
import net.minestom.server.UpdateManager; import net.minestom.server.UpdateManager;
import net.minestom.server.adventure.audience.PacketGroupingAudience; 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.Data;
import net.minestom.server.data.DataContainer; import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.Entity; 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.Tag;
import net.minestom.server.tag.TagHandler; import net.minestom.server.tag.TagHandler;
import net.minestom.server.thread.ThreadProvider; import net.minestom.server.thread.ThreadProvider;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.PacketUtils; 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.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils; 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.entity.EntityUtils;
import net.minestom.server.utils.time.Cooldown; import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.time.TimeUnit;
@ -309,10 +308,10 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
* <p> * <p>
* Always returning false allow entities to survive in the void. * Always returning false allow entities to survive in the void.
* *
* @param position the position in the world * @param point the point in the world
* @return true iif position is inside the void * @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}. * 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 * @param callback the optional callback to run when the chunk is loaded
*/ */
public void loadChunk(@NotNull Position position, @Nullable ChunkCallback callback) { public void loadChunk(@NotNull Point point, @Nullable ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate(position.getX()); final int chunkX = ChunkUtils.getChunkCoordinate(point.x());
final int chunkZ = ChunkUtils.getChunkCoordinate(position.getZ()); final int chunkZ = ChunkUtils.getChunkCoordinate(point.z());
loadChunk(chunkX, chunkZ, callback); loadChunk(chunkX, chunkZ, callback);
} }
/** /**
* Loads a {@link Chunk} (if {@link #hasEnabledAutoChunkLoad()} returns true) * 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) * @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) { public void loadOptionalChunk(@NotNull Point point, @Nullable ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate(position.getX()); final int chunkX = ChunkUtils.getChunkCoordinate(point.x());
final int chunkZ = ChunkUtils.getChunkCoordinate(position.getZ()); final int chunkZ = ChunkUtils.getChunkCoordinate(point.z());
loadOptionalChunk(chunkX, chunkZ, callback); 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 * @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 * @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); final Block block = getBlock(blockPosition);
BlockActionPacket blockActionPacket = new BlockActionPacket(); 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 x the X position
* @param z the Z position * @param z the Z position
* @return the chunk at the given position, null if not loaded * @return the chunk at the given position, null if not loaded
*/ */
@Nullable public @Nullable Chunk getChunkAt(double x, double z) {
public Chunk getChunkAt(double x, double z) {
final int chunkX = ChunkUtils.getChunkCoordinate(x); final int chunkX = ChunkUtils.getChunkCoordinate(x);
final int chunkZ = ChunkUtils.getChunkCoordinate(z); final int chunkZ = ChunkUtils.getChunkCoordinate(z);
return getChunk(chunkX, chunkZ); return getChunk(chunkX, chunkZ);
@ -620,8 +618,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
* @param point the chunk position * @param point the chunk position
* @return the chunk at the given position, null if not loaded * @return the chunk at the given position, null if not loaded
*/ */
@Nullable public @Nullable Chunk getChunkAt(@NotNull Point point) {
public Chunk getChunkAt(@NotNull Point point) {
return getChunkAt(point.x(), point.z()); 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); AddEntityToInstanceEvent event = new AddEntityToInstanceEvent(this, entity);
EventDispatcher.callCancellable(event, () -> { EventDispatcher.callCancellable(event, () -> {
final Position entityPosition = entity.getPosition(); final Pos entityPosition = entity.getPosition();
final boolean isPlayer = entity instanceof Player; final boolean isPlayer = entity instanceof Player;
if (isPlayer) { if (isPlayer) {

View File

@ -1,6 +1,8 @@
package net.minestom.server.instance; package net.minestom.server.instance;
import net.minestom.server.MinecraftServer; 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.Data;
import net.minestom.server.data.SerializableData; import net.minestom.server.data.SerializableData;
import net.minestom.server.entity.Player; 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.storage.StorageLocation;
import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.PacketUtils; import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.callback.OptionalCallback; import net.minestom.server.utils.callback.OptionalCallback;
import net.minestom.server.utils.chunk.ChunkCallback; import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkSupplier; import net.minestom.server.utils.chunk.ChunkSupplier;
import net.minestom.server.utils.chunk.ChunkUtils; 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.utils.validate.Check;
import net.minestom.server.world.DimensionType; import net.minestom.server.world.DimensionType;
import net.minestom.server.world.biomes.Biome; import net.minestom.server.world.biomes.Biome;
@ -60,7 +60,7 @@ public class InstanceContainer extends Instance {
protected final Set<Chunk> scheduledChunksToRemove = new HashSet<>(); protected final Set<Chunk> scheduledChunksToRemove = new HashSet<>();
private final ReadWriteLock changingBlockLock = new ReentrantReadWriteLock(); 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 // the chunk loader, used when trying to load/save a chunk from another source
private IChunkLoader chunkLoader; private IChunkLoader chunkLoader;
@ -138,7 +138,7 @@ public class InstanceContainer extends Instance {
synchronized (chunk) { synchronized (chunk) {
// Refresh the last block change time // Refresh the last block change time
this.lastBlockChangeTime = System.currentTimeMillis(); 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. if (isAlreadyChanged(blockPosition, block)) { // do NOT change the block again.
// Avoids StackOverflowExceptions when onDestroy tries to destroy the block itself // 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 // 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 @Override
public boolean isInVoid(@NotNull Position position) { public boolean isInVoid(@NotNull Point point) {
// TODO: customizable // 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> * <p>
* WARNING: this does not change the internal block data, this is strictly visual for the players. * 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 blockPosition the block position
* @param block the new block * @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())); 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); currentlyChangingBlocks.put(blockPosition, block);
} }
@ -650,7 +650,7 @@ public class InstanceContainer extends Instance {
* @param block the block * @param block the block
* @return true if the block changed since the last update * @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); final Block changedBlock = currentlyChangingBlocks.get(blockPosition);
if (changedBlock == null) if (changedBlock == null)
return false; return false;
@ -664,7 +664,7 @@ public class InstanceContainer extends Instance {
* @param blockPosition the block position * @param blockPosition the block position
* @return the modified block state id * @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); final BlockPlacementRule blockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(block);
if (blockPlacementRule != null) { if (blockPlacementRule != null) {
return blockPlacementRule.blockUpdate(this, blockPosition, block); return blockPlacementRule.blockUpdate(this, blockPosition, block);
@ -679,15 +679,15 @@ public class InstanceContainer extends Instance {
* *
* @param blockPosition the position of the modified block * @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 offsetX = -1; offsetX < 2; offsetX++) {
for (int offsetY = -1; offsetY < 2; offsetY++) { for (int offsetY = -1; offsetY < 2; offsetY++) {
for (int offsetZ = -1; offsetZ < 2; offsetZ++) { for (int offsetZ = -1; offsetZ < 2; offsetZ++) {
if (offsetX == 0 && offsetY == 0 && offsetZ == 0) if (offsetX == 0 && offsetY == 0 && offsetZ == 0)
continue; continue;
final int neighborX = blockPosition.getX() + offsetX; final int neighborX = blockPosition.blockX() + offsetX;
final int neighborY = blockPosition.getY() + offsetY; final int neighborY = blockPosition.blockY() + offsetY;
final int neighborZ = blockPosition.getZ() + offsetZ; final int neighborZ = blockPosition.blockZ() + offsetZ;
final Chunk chunk = getChunkAt(neighborX, neighborZ); final Chunk chunk = getChunkAt(neighborX, neighborZ);
// Do not try to get neighbour in an unloaded chunk // 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 Block neighborBlock = chunk.getBlock(neighborX, neighborY, neighborZ);
final BlockPlacementRule neighborBlockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(neighborBlock); final BlockPlacementRule neighborBlockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(neighborBlock);
if (neighborBlockPlacementRule != null) { 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, final Block newNeighborBlock = neighborBlockPlacementRule.blockUpdate(this,
neighborPosition, neighborBlock); neighborPosition, neighborBlock);
if (neighborBlock != newNeighborBlock) { 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.Block;
import net.minestom.server.instance.block.BlockFace; import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.storage.StorageLocation; import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.chunk.ChunkCallback; 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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -119,8 +118,8 @@ public class SharedInstance extends Instance {
} }
@Override @Override
public boolean isInVoid(@NotNull Position position) { public boolean isInVoid(@NotNull Point point) {
return instanceContainer.isInVoid(position); 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.ServerPacket;
import net.minestom.server.network.packet.server.play.*; import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.utils.PacketUtils; import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.Position; import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull; 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. * 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 * @return the axis where the position collides with the world border
*/ */
@NotNull public @NotNull CollisionAxis getCollisionAxis(@NotNull Point point) {
public CollisionAxis getCollisionAxis(@NotNull Position position) {
final double radius = getDiameter() / 2d; final double radius = getDiameter() / 2d;
final boolean checkX = position.getX() <= getCenterX() + radius && position.getX() >= getCenterX() - radius; final boolean checkX = point.x() <= getCenterX() + radius && point.x() >= getCenterX() - radius;
final boolean checkZ = position.getZ() <= getCenterZ() + radius && position.getZ() >= getCenterZ() - radius; final boolean checkZ = point.z() <= getCenterZ() + radius && point.z() >= getCenterZ() - radius;
if (!checkX && !checkZ) { if (!checkX && !checkZ) {
return CollisionAxis.BOTH; return CollisionAxis.BOTH;
} else if (!checkX) { } else if (!checkX) {
@ -180,11 +179,11 @@ public class WorldBorder {
/** /**
* Used to know if a position is located inside the world border or not. * 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 * @return true if {@code position} is inside the world border, false otherwise
*/ */
public boolean isInside(@NotNull Position position) { public boolean isInside(@NotNull Point point) {
return getCollisionAxis(position) == CollisionAxis.NONE; 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.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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 * @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} * @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) { public AbsoluteBlockBatch apply(@NotNull Instance instance, @NotNull Point position, @Nullable Runnable callback) {
return apply(instance, position.getX(), position.getY(), position.getZ(), callback); return apply(instance, position.blockX(), position.blockY(), position.blockZ(), callback);
} }
/** /**

View File

@ -1,6 +1,6 @@
package net.minestom.server.instance.block; package net.minestom.server.instance.block;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public interface BlockGetter { 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.instance.Instance;
import net.minestom.server.tag.Tag; import net.minestom.server.tag.Tag;
import net.minestom.server.utils.NamespaceID; 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.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -1,8 +1,8 @@
package net.minestom.server.instance.block; package net.minestom.server.instance.block;
import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.minestom.server.instance.batch.Batch; import net.minestom.server.instance.batch.Batch;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull;
public interface BlockSetter { public interface BlockSetter {
void setBlock(int x, int y, int z, @NotNull Block block); void setBlock(int x, int y, int z, @NotNull Block block);
default void setBlock(@NotNull BlockPosition blockPosition, @NotNull Block block) { default void setBlock(@NotNull Point blockPosition, @NotNull Block block) {
setBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), 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.Instance;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace; 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.NotNull;
import org.jetbrains.annotations.Nullable; 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.Block;
import net.minestom.server.instance.block.BlockFace; import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.instance.block.rule.BlockPlacementRule; 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 org.jetbrains.annotations.NotNull;
public class AxisPlacementRule extends BlockPlacementRule { 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.BlockFace;
import net.minestom.server.instance.block.rule.BlockPlacementRule; import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.utils.block.BlockUtils; 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 org.jetbrains.annotations.NotNull;
import java.util.Map; import java.util.Map;

View File

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

View File

@ -1,8 +1,9 @@
package net.minestom.server.item.metadata; 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.ItemMeta;
import net.minestom.server.item.ItemMetaBuilder; import net.minestom.server.item.ItemMetaBuilder;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBTCompound; 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 boolean lodestoneTracked;
private final String lodestoneDimension; private final String lodestoneDimension;
private final Position lodestonePosition; private final Point lodestonePosition;
protected CompassMeta(ItemMetaBuilder metaBuilder, protected CompassMeta(ItemMetaBuilder metaBuilder,
boolean lodestoneTracked, boolean lodestoneTracked,
@Nullable String lodestoneDimension, @Nullable String lodestoneDimension,
@Nullable Position lodestonePosition) { @Nullable Point lodestonePosition) {
super(metaBuilder); super(metaBuilder);
this.lodestoneTracked = lodestoneTracked; this.lodestoneTracked = lodestoneTracked;
this.lodestoneDimension = lodestoneDimension; this.lodestoneDimension = lodestoneDimension;
@ -33,7 +34,7 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
return lodestoneDimension; return lodestoneDimension;
} }
public @Nullable Position getLodestonePosition() { public @Nullable Point getLodestonePosition() {
return lodestonePosition; return lodestonePosition;
} }
@ -41,7 +42,7 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
private boolean lodestoneTracked; private boolean lodestoneTracked;
private String lodestoneDimension; private String lodestoneDimension;
private Position lodestonePosition; private Point lodestonePosition;
public Builder lodestoneTracked(boolean lodestoneTracked) { public Builder lodestoneTracked(boolean lodestoneTracked) {
this.lodestoneTracked = lodestoneTracked; this.lodestoneTracked = lodestoneTracked;
@ -63,15 +64,15 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
return this; return this;
} }
public Builder lodestonePosition(@Nullable Position lodestonePosition) { public Builder lodestonePosition(@Nullable Point lodestonePosition) {
this.lodestonePosition = lodestonePosition; this.lodestonePosition = lodestonePosition;
mutateNbt(compound -> { mutateNbt(compound -> {
if (lodestonePosition != null) { if (lodestonePosition != null) {
NBTCompound posCompound = new NBTCompound(); NBTCompound posCompound = new NBTCompound();
posCompound.setInt("X", (int) lodestonePosition.getX()); posCompound.setInt("X", lodestonePosition.blockX());
posCompound.setInt("Y", (int) lodestonePosition.getY()); posCompound.setInt("Y", lodestonePosition.blockY());
posCompound.setInt("Z", (int) lodestonePosition.getZ()); posCompound.setInt("Z", lodestonePosition.blockZ());
compound.set("LodestonePos", posCompound); compound.set("LodestonePos", posCompound);
} else { } else {
compound.removeTag("LodestonePos"); compound.removeTag("LodestonePos");
@ -99,7 +100,7 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
final int x = posCompound.getInt("X"); final int x = posCompound.getInt("X");
final int y = posCompound.getInt("Y"); final int y = posCompound.getInt("Y");
final int z = posCompound.getInt("Z"); 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.network.packet.server.play.BlockChangePacket;
import net.minestom.server.utils.Direction; import net.minestom.server.utils.Direction;
import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
import java.util.Set; 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.item.StackingRule;
import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket; import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket;
import net.minestom.server.network.packet.server.play.AcknowledgePlayerDiggingPacket; import net.minestom.server.network.packet.server.play.AcknowledgePlayerDiggingPacket;
import net.minestom.server.utils.BlockPosition; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Point;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class PlayerDiggingListener { public class PlayerDiggingListener {
@ -150,11 +149,10 @@ public class PlayerDiggingListener {
if (!result) { if (!result) {
if (block.isSolid()) { 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 // Teleport the player back if he broke a solid block just below him
if (playerBlockPosition.subtract(0, 1, 0).equals(blockPosition)) if (playerPosition.sub(0, 1, 0).samePoint(blockPosition))
player.teleport(player.getPosition()); 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.event.player.PlayerMoveEvent;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.minestom.server.network.packet.client.play.*; 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.utils.chunk.ChunkUtils;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class PlayerPositionListener { public class PlayerPositionListener {
@ -16,10 +16,10 @@ public class PlayerPositionListener {
} }
public static void playerLookListener(ClientPlayerRotationPacket packet, Player player) { public static void playerLookListener(ClientPlayerRotationPacket packet, Player player) {
final Position playerPosition = player.getPosition(); final var playerPosition = player.getPosition();
final double x = playerPosition.getX(); final double x = playerPosition.x();
final double y = playerPosition.getY(); final double y = playerPosition.y();
final double z = playerPosition.getZ(); final double z = playerPosition.z();
final float yaw = packet.yaw; final float yaw = packet.yaw;
final float pitch = packet.pitch; final float pitch = packet.pitch;
final boolean onGround = packet.onGround; final boolean onGround = packet.onGround;
@ -27,9 +27,9 @@ public class PlayerPositionListener {
} }
public static void playerPositionListener(ClientPlayerPositionPacket packet, Player player) { public static void playerPositionListener(ClientPlayerPositionPacket packet, Player player) {
final Position playerPosition = player.getPosition(); final var playerPosition = player.getPosition();
final float yaw = playerPosition.getYaw(); final float yaw = playerPosition.yaw();
final float pitch = playerPosition.getPitch(); final float pitch = playerPosition.pitch();
final boolean onGround = packet.onGround; final boolean onGround = packet.onGround;
processMovement(player, processMovement(player,
packet.x, packet.y, packet.z, 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, private static void processMovement(@NotNull Player player, double x, double y, double z,
float yaw, float pitch, boolean onGround) { float yaw, float pitch, boolean onGround) {
final Instance instance = player.getInstance(); final Instance instance = player.getInstance();
// Prevent moving before the player spawned, probably a modified client (or high latency?) // Prevent moving before the player spawned, probably a modified client (or high latency?)
if (instance == null) { if (instance == null) {
return; return;
} }
// Prevent the player from moving during a teleport // Prevent the player from moving during a teleport
if (player.getLastSentTeleportId() != player.getLastReceivedTeleportId()) { if (player.getLastSentTeleportId() != player.getLastReceivedTeleportId()) {
return; return;
} }
// Try to move in an unloaded chunk, prevent it // Try to move in an unloaded chunk, prevent it
if (!ChunkUtils.isLoaded(instance, x, z)) { if (!ChunkUtils.isLoaded(instance, x, z)) {
player.teleport(player.getPosition()); player.teleport(player.getPosition());
return; return;
} }
final Position currentPosition = player.getPosition().clone(); final var currentPosition = player.getPosition();
Position newPosition = new Position(x, y, z, yaw, pitch); final var newPosition = new Pos(x, y, z, yaw, pitch);
final Position cachedPosition = newPosition.clone();
PlayerMoveEvent playerMoveEvent = new PlayerMoveEvent(player, newPosition); PlayerMoveEvent playerMoveEvent = new PlayerMoveEvent(player, newPosition);
EventDispatcher.call(playerMoveEvent); EventDispatcher.call(playerMoveEvent);
// True if the event call changed the player position (possibly a teleport) // True if the event call changed the player position (possibly a teleport)
final boolean positionChanged = !currentPosition.equals(player.getPosition()); final boolean positionChanged = !currentPosition.equals(player.getPosition());
if (!playerMoveEvent.isCancelled() && !positionChanged) { if (!playerMoveEvent.isCancelled() && !positionChanged) {
// Move the player // Move the player
newPosition = playerMoveEvent.getNewPosition(); player.refreshPosition(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.refreshOnGround(onGround); player.refreshOnGround(onGround);
} else { } else {
// Cancelled, teleport to previous position
player.teleport(player.getPosition()); 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.ClientSteerBoatPacket;
import net.minestom.server.network.packet.client.play.ClientSteerVehiclePacket; import net.minestom.server.network.packet.client.play.ClientSteerVehiclePacket;
import net.minestom.server.network.packet.client.play.ClientVehicleMovePacket; import net.minestom.server.network.packet.client.play.ClientVehicleMovePacket;
import net.minestom.server.utils.Position; import net.minestom.server.coordinate.Pos;
public class PlayerVehicleListener { public class PlayerVehicleListener {
@ -19,11 +19,10 @@ public class PlayerVehicleListener {
public static void vehicleMoveListener(ClientVehicleMovePacket packet, Player player) { public static void vehicleMoveListener(ClientVehicleMovePacket packet, Player player) {
final Entity vehicle = player.getVehicle(); final Entity vehicle = player.getVehicle();
if (vehicle == null) if (vehicle == null)
return; 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); vehicle.refreshPosition(newPosition);
// This packet causes weird screen distortion // This packet causes weird screen distortion
@ -39,7 +38,6 @@ public class PlayerVehicleListener {
public static void boatSteerListener(ClientSteerBoatPacket packet, Player player) { public static void boatSteerListener(ClientSteerBoatPacket packet, Player player) {
final Entity vehicle = player.getVehicle(); final Entity vehicle = player.getVehicle();
if (!(vehicle.getEntityMeta() instanceof BoatMeta)) if (!(vehicle.getEntityMeta() instanceof BoatMeta))
return; return;
@ -47,5 +45,4 @@ public class PlayerVehicleListener {
boat.setLeftPaddleTurning(packet.leftPaddleTurning); boat.setLeftPaddleTurning(packet.leftPaddleTurning);
boat.setRightPaddleTurning(packet.rightPaddleTurning); 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.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ClientGenerateStructurePacket extends ClientPlayPacket { 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.entity.Player;
import net.minestom.server.instance.block.BlockFace; import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.network.packet.client.ClientPlayPacket; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ClientPlayerBlockPlacementPacket extends ClientPlayPacket { 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.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ClientPlayerDiggingPacket extends ClientPlayPacket { 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.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ClientQueryBlockNbtPacket extends ClientPlayPacket { 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.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ClientUpdateCommandBlockPacket extends ClientPlayPacket { 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.network.packet.client.ClientPlayPacket;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ClientUpdateSignPacket extends ClientPlayPacket { 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.Rotation;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ClientUpdateStructureBlockPacket extends ClientPlayPacket { 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.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class AcknowledgePlayerDiggingPacket implements ServerPacket { 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.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class BlockActionPacket implements ServerPacket { 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.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class BlockBreakAnimationPacket implements ServerPacket { 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.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class BlockChangePacket implements ServerPacket { 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.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBT; import org.jglrxavpok.hephaistos.nbt.NBT;
import org.jglrxavpok.hephaistos.nbt.NBTCompound; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.tag.Tag; import net.minestom.server.tag.Tag;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Utils; import net.minestom.server.utils.Utils;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
@ -147,11 +146,11 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket {
} }
if (resultNbt.getSize() > 0) { 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()) resultNbt.setString("id", handler.getNamespaceId().asString())
.setInt("x", blockPosition.getX()) .setInt("x", blockPosition.blockX())
.setInt("y", blockPosition.getY()) .setInt("y", blockPosition.blockY())
.setInt("z", blockPosition.getZ()); .setInt("z", blockPosition.blockZ());
compounds.add(resultNbt); 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.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class EffectPacket implements ServerPacket { 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class EntityPositionAndRotationPacket implements ServerPacket { public class EntityPositionAndRotationPacket implements ServerPacket {
@ -14,7 +14,8 @@ public class EntityPositionAndRotationPacket implements ServerPacket {
public float yaw, pitch; public float yaw, pitch;
public boolean onGround; public boolean onGround;
public EntityPositionAndRotationPacket() {} public EntityPositionAndRotationPacket() {
}
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
@ -44,15 +45,15 @@ public class EntityPositionAndRotationPacket implements ServerPacket {
} }
public static EntityPositionAndRotationPacket getPacket(int entityId, public static EntityPositionAndRotationPacket getPacket(int entityId,
@NotNull Position newPosition, @NotNull Position oldPosition, @NotNull Pos newPosition, @NotNull Pos oldPosition,
boolean onGround) { boolean onGround) {
EntityPositionAndRotationPacket entityPositionAndRotationPacket = new EntityPositionAndRotationPacket(); EntityPositionAndRotationPacket entityPositionAndRotationPacket = new EntityPositionAndRotationPacket();
entityPositionAndRotationPacket.entityId = entityId; entityPositionAndRotationPacket.entityId = entityId;
entityPositionAndRotationPacket.deltaX = (short) ((newPosition.getX() * 32 - oldPosition.getX() * 32) * 128); entityPositionAndRotationPacket.deltaX = (short) ((newPosition.x() * 32 - oldPosition.x() * 32) * 128);
entityPositionAndRotationPacket.deltaY = (short) ((newPosition.getY() * 32 - oldPosition.getY() * 32) * 128); entityPositionAndRotationPacket.deltaY = (short) ((newPosition.y() * 32 - oldPosition.y() * 32) * 128);
entityPositionAndRotationPacket.deltaZ = (short) ((newPosition.getZ() * 32 - oldPosition.getZ() * 32) * 128); entityPositionAndRotationPacket.deltaZ = (short) ((newPosition.z() * 32 - oldPosition.z() * 32) * 128);
entityPositionAndRotationPacket.yaw = newPosition.getYaw(); entityPositionAndRotationPacket.yaw = newPosition.yaw();
entityPositionAndRotationPacket.pitch = newPosition.getPitch(); entityPositionAndRotationPacket.pitch = newPosition.pitch();
entityPositionAndRotationPacket.onGround = onGround; entityPositionAndRotationPacket.onGround = onGround;
return entityPositionAndRotationPacket; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class EntityPositionPacket implements ServerPacket { public class EntityPositionPacket implements ServerPacket {
@ -13,7 +13,8 @@ public class EntityPositionPacket implements ServerPacket {
public short deltaX, deltaY, deltaZ; public short deltaX, deltaY, deltaZ;
public boolean onGround; public boolean onGround;
public EntityPositionPacket() {} public EntityPositionPacket() {
}
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
@ -40,13 +41,13 @@ public class EntityPositionPacket implements ServerPacket {
@NotNull @NotNull
public static EntityPositionPacket getPacket(int entityId, public static EntityPositionPacket getPacket(int entityId,
@NotNull Position newPosition, @NotNull Position oldPosition, @NotNull Pos newPosition, @NotNull Pos oldPosition,
boolean onGround) { boolean onGround) {
EntityPositionPacket entityPositionPacket = new EntityPositionPacket(); EntityPositionPacket entityPositionPacket = new EntityPositionPacket();
entityPositionPacket.entityId = entityId; entityPositionPacket.entityId = entityId;
entityPositionPacket.deltaX = (short) ((newPosition.getX() * 32 - oldPosition.getX() * 32) * 128); entityPositionPacket.deltaX = (short) ((newPosition.x() * 32 - oldPosition.x() * 32) * 128);
entityPositionPacket.deltaY = (short) ((newPosition.getY() * 32 - oldPosition.getY() * 32) * 128); entityPositionPacket.deltaY = (short) ((newPosition.y() * 32 - oldPosition.y() * 32) * 128);
entityPositionPacket.deltaZ = (short) ((newPosition.getZ() * 32 - oldPosition.getZ() * 32) * 128); entityPositionPacket.deltaZ = (short) ((newPosition.z() * 32 - oldPosition.z() * 32) * 128);
entityPositionPacket.onGround = onGround; entityPositionPacket.onGround = onGround;
return entityPositionPacket; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class EntityTeleportPacket implements ServerPacket { public class EntityTeleportPacket implements ServerPacket {
public int entityId; public int entityId;
public Position position; public Pos position;
public boolean onGround; public boolean onGround;
public EntityTeleportPacket() { public EntityTeleportPacket() {
position = new Position(); position = Pos.ZERO;
} }
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(entityId); writer.writeVarInt(entityId);
writer.writeDouble(position.getX()); writer.writeDouble(position.x());
writer.writeDouble(position.getY()); writer.writeDouble(position.y());
writer.writeDouble(position.getZ()); writer.writeDouble(position.z());
writer.writeByte((byte) (position.getYaw() * 256f / 360f)); writer.writeByte((byte) (position.yaw() * 256f / 360f));
writer.writeByte((byte) (position.getPitch() * 256f / 360f)); writer.writeByte((byte) (position.pitch() * 256f / 360f));
writer.writeBoolean(onGround); writer.writeBoolean(onGround);
} }
@Override @Override
public void read(@NotNull BinaryReader reader) { public void read(@NotNull BinaryReader reader) {
entityId = reader.readVarInt(); entityId = reader.readVarInt();
position = new Position( position = new Pos(
reader.readDouble(), reader.readDouble(),
reader.readDouble(), reader.readDouble(),
reader.readDouble(), reader.readDouble(),
reader.readByte() * 360f / 256f, reader.readByte() * 360f / 256f,
reader.readByte() * 360f / 256f reader.readByte() * 360f / 256f
); );
onGround = reader.readBoolean(); 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.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class OpenSignEditorPacket implements ServerPacket { 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class PlayerPositionAndLookPacket implements ServerPacket { public class PlayerPositionAndLookPacket implements ServerPacket {
public Position position; public Pos position;
public byte flags; public byte flags;
public int teleportId; public int teleportId;
public boolean dismountVehicle; public boolean dismountVehicle;
public PlayerPositionAndLookPacket() { public PlayerPositionAndLookPacket() {
position = new Position(); position = Pos.ZERO;
} }
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
writer.writeDouble(position.getX()); writer.writeDouble(position.x());
writer.writeDouble(position.getY()); writer.writeDouble(position.y());
writer.writeDouble(position.getZ()); writer.writeDouble(position.z());
writer.writeFloat(position.getYaw()); writer.writeFloat(position.yaw());
writer.writeFloat(position.getPitch()); writer.writeFloat(position.pitch());
writer.writeByte(flags); writer.writeByte(flags);
writer.writeVarInt(teleportId); writer.writeVarInt(teleportId);
@ -34,7 +34,7 @@ public class PlayerPositionAndLookPacket implements ServerPacket {
@Override @Override
public void read(@NotNull BinaryReader reader) { 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(); flags = reader.readByte();
teleportId = reader.readVarInt(); teleportId = reader.readVarInt();

View File

@ -1,5 +1,6 @@
package net.minestom.server.network.packet.server.play; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.BlockPosition;
@ -9,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
public class SculkVibrationSignal implements ServerPacket { public class SculkVibrationSignal implements ServerPacket {
public BlockPosition position; public Point position;
public String destinationIdentifier; public String destinationIdentifier;
// TODO 'varies' destination // TODO 'varies' destination
public int arrivalTicks; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.sound.SoundEvent; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class SoundEffectPacket implements ServerPacket { public class SoundEffectPacket implements ServerPacket {
@ -23,18 +23,19 @@ public class SoundEffectPacket implements ServerPacket {
} }
@NotNull @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(); SoundEffectPacket packet = new SoundEffectPacket();
packet.soundId = sound.getId(); packet.soundId = sound.getId();
packet.soundSource = category; packet.soundSource = category;
// *8 converts to fixed-point representation with 3 bits for fractional part // *8 converts to fixed-point representation with 3 bits for fractional part
packet.x = (int) position.getX(); packet.x = (int) position.x();
packet.y = (int) position.getY(); packet.y = (int) position.y();
packet.z = (int) position.getZ(); packet.z = (int) position.z();
packet.volume = volume; packet.volume = volume;
packet.pitch = pitch; packet.pitch = pitch;
return packet; return packet;
} }
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(soundId); writer.writeVarInt(soundId);
@ -50,9 +51,9 @@ public class SoundEffectPacket implements ServerPacket {
public void read(@NotNull BinaryReader reader) { public void read(@NotNull BinaryReader reader) {
soundId = reader.readVarInt(); soundId = reader.readVarInt();
soundSource = Source.values()[reader.readVarInt()]; soundSource = Source.values()[reader.readVarInt()];
x = reader.readInt()/8; x = reader.readInt() / 8;
y = reader.readInt()/8; y = reader.readInt() / 8;
z = reader.readInt()/8; z = reader.readInt() / 8;
volume = reader.readFloat(); volume = reader.readFloat();
pitch = 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.UUID; import java.util.UUID;
@ -14,13 +14,13 @@ public class SpawnEntityPacket implements ServerPacket {
public int entityId; public int entityId;
public UUID uuid; public UUID uuid;
public int type; public int type;
public Position position; public Pos position;
public int data; public int data;
public short velocityX, velocityY, velocityZ; public short velocityX, velocityY, velocityZ;
public SpawnEntityPacket() { public SpawnEntityPacket() {
uuid = new UUID(0, 0); uuid = new UUID(0, 0);
position = new Position(); position = Pos.ZERO;
} }
@Override @Override
@ -29,12 +29,12 @@ public class SpawnEntityPacket implements ServerPacket {
writer.writeUuid(uuid); writer.writeUuid(uuid);
writer.writeVarInt(type); writer.writeVarInt(type);
writer.writeDouble(position.getX()); writer.writeDouble(position.x());
writer.writeDouble(position.getY()); writer.writeDouble(position.y());
writer.writeDouble(position.getZ()); writer.writeDouble(position.z());
writer.writeByte((byte) (position.getYaw() * 256 / 360)); writer.writeByte((byte) (position.yaw() * 256 / 360));
writer.writeByte((byte) (position.getPitch() * 256 / 360)); writer.writeByte((byte) (position.pitch() * 256 / 360));
writer.writeInt(data); writer.writeInt(data);
@ -49,10 +49,9 @@ public class SpawnEntityPacket implements ServerPacket {
uuid = reader.readUuid(); uuid = reader.readUuid();
type = reader.readVarInt(); type = reader.readVarInt();
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble()); position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(),
reader.readByte() * 360f / 256f,
position.setYaw(reader.readByte() * 360f / 256f); reader.readByte() * 360f / 256f);
position.setPitch(reader.readByte() * 360f / 256f);
data = reader.readInt(); 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class SpawnExperienceOrbPacket implements ServerPacket { public class SpawnExperienceOrbPacket implements ServerPacket {
public int entityId; public int entityId;
public Position position; public Pos position;
public short expCount; public short expCount;
public SpawnExperienceOrbPacket() { public SpawnExperienceOrbPacket() {
position = new Position(); position = Pos.ZERO;
} }
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(entityId); writer.writeVarInt(entityId);
writer.writeDouble(position.getX()); writer.writeDouble(position.x());
writer.writeDouble(position.getY()); writer.writeDouble(position.y());
writer.writeDouble(position.getZ()); writer.writeDouble(position.z());
writer.writeShort(expCount); writer.writeShort(expCount);
} }
@Override @Override
public void read(@NotNull BinaryReader reader) { public void read(@NotNull BinaryReader reader) {
entityId = reader.readVarInt(); entityId = reader.readVarInt();
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble()); position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble());
expCount = reader.readShort(); 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.UUID; import java.util.UUID;
@ -14,13 +14,13 @@ public class SpawnLivingEntityPacket implements ServerPacket {
public int entityId; public int entityId;
public UUID entityUuid; public UUID entityUuid;
public int entityType; public int entityType;
public Position position; public Pos position;
public float headPitch; public float headPitch;
public short velocityX, velocityY, velocityZ; public short velocityX, velocityY, velocityZ;
public SpawnLivingEntityPacket() { public SpawnLivingEntityPacket() {
entityUuid = new UUID(0, 0); entityUuid = new UUID(0, 0);
position = new Position(); position = Pos.ZERO;
} }
@Override @Override
@ -29,12 +29,12 @@ public class SpawnLivingEntityPacket implements ServerPacket {
writer.writeUuid(entityUuid); writer.writeUuid(entityUuid);
writer.writeVarInt(entityType); writer.writeVarInt(entityType);
writer.writeDouble(position.getX()); writer.writeDouble(position.x());
writer.writeDouble(position.getY()); writer.writeDouble(position.y());
writer.writeDouble(position.getZ()); writer.writeDouble(position.z());
writer.writeByte((byte) (position.getYaw() * 256 / 360)); writer.writeByte((byte) (position.yaw() * 256 / 360));
writer.writeByte((byte) (position.getPitch() * 256 / 360)); writer.writeByte((byte) (position.pitch() * 256 / 360));
writer.writeByte((byte) (headPitch * 256 / 360)); writer.writeByte((byte) (headPitch * 256 / 360));
writer.writeShort(velocityX); writer.writeShort(velocityX);
@ -48,10 +48,9 @@ public class SpawnLivingEntityPacket implements ServerPacket {
entityUuid = reader.readUuid(); entityUuid = reader.readUuid();
entityType = reader.readVarInt(); entityType = reader.readVarInt();
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble()); position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(),
reader.readByte() * 360f / 256f,
position.setYaw(reader.readByte() * 360f / 256f); reader.readByte() * 360f / 256f);
position.setPitch(reader.readByte() * 360f / 256f);
headPitch = reader.readByte() * 360f / 256f; headPitch = reader.readByte() * 360f / 256f;
velocityX = reader.readShort(); 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.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.UUID; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; 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.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.coordinate.Pos;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.UUID; import java.util.UUID;
@ -13,31 +13,31 @@ public class SpawnPlayerPacket implements ServerPacket {
public int entityId; public int entityId;
public UUID playerUuid; public UUID playerUuid;
public Position position; public Pos position;
public SpawnPlayerPacket() { public SpawnPlayerPacket() {
playerUuid = new UUID(0,0); playerUuid = new UUID(0, 0);
position = new Position(); position = Pos.ZERO;
} }
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(entityId); writer.writeVarInt(entityId);
writer.writeUuid(playerUuid); writer.writeUuid(playerUuid);
writer.writeDouble(position.getX()); writer.writeDouble(position.x());
writer.writeDouble(position.getY()); writer.writeDouble(position.y());
writer.writeDouble(position.getZ()); writer.writeDouble(position.z());
writer.writeByte((byte) (position.getYaw() * 256f / 360f)); writer.writeByte((byte) (position.yaw() * 256f / 360f));
writer.writeByte((byte) (position.getPitch() * 256f / 360f)); writer.writeByte((byte) (position.pitch() * 256f / 360f));
} }
@Override @Override
public void read(@NotNull BinaryReader reader) { public void read(@NotNull BinaryReader reader) {
entityId = reader.readVarInt(); this.entityId = reader.readVarInt();
playerUuid = reader.readUuid(); this.playerUuid = reader.readUuid();
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble()); this.position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(),
position.setYaw((reader.readByte() * 360f) / 256f); (reader.readByte() * 360f) / 256f,
position.setPitch((reader.readByte() * 360f) / 256f); (reader.readByte() * 360f) / 256f);
} }
@Override @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.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class SpawnPositionPacket implements ServerPacket { public class SpawnPositionPacket implements ServerPacket {

View File

@ -1,8 +1,7 @@
package net.minestom.server.utils; package net.minestom.server.utils;
import net.minestom.server.instance.block.BlockFace; import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.clone.PublicCloneable; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.coordinate.Point;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Objects; 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. * 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 @Deprecated
public class BlockPosition implements Point { public class BlockPosition implements Point {

View File

@ -1,7 +1,7 @@
package net.minestom.server.utils; package net.minestom.server.utils;
import net.minestom.server.utils.chunk.ChunkUtils; 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 org.jetbrains.annotations.NotNull;
import java.util.Objects; import java.util.Objects;
@ -11,7 +11,7 @@ import java.util.function.DoubleUnaryOperator;
* Represents a position. * Represents a position.
* The instance is not contained. * 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 @Deprecated
public class Position implements Point { public class Position implements Point {

View File

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

View File

@ -1,14 +1,12 @@
package net.minestom.server.utils; package net.minestom.server.utils;
import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Point;
import net.minestom.server.utils.clone.PublicCloneable;
import net.minestom.server.utils.coordinate.Point;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.DoubleUnaryOperator; 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 @Deprecated
public class Vector implements Point { 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.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minestom.server.chat.JsonMessage; import net.minestom.server.chat.JsonMessage;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.NBTUtils; import net.minestom.server.utils.NBTUtils;
import net.minestom.server.utils.SerializerUtils; import net.minestom.server.utils.SerializerUtils;
import net.minestom.server.utils.Utils; 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 net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBT; import org.jglrxavpok.hephaistos.nbt.NBT;

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