mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-02 14:38:26 +01:00
Initial position api implementation
This commit is contained in:
parent
6275154997
commit
28dca16b29
@ -15,7 +15,6 @@ import net.minestom.server.network.packet.server.play.SoundEffectPacket;
|
||||
import net.minestom.server.network.packet.server.play.StopSoundPacket;
|
||||
import net.minestom.server.registry.Registries;
|
||||
import net.minestom.server.sound.SoundEvent;
|
||||
import net.minestom.server.utils.Position;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -25,6 +24,7 @@ import java.util.Collection;
|
||||
*/
|
||||
public class AdventurePacketConvertor {
|
||||
private static final Object2IntMap<NamedTextColor> NAMED_TEXT_COLOR_ID_MAP = new Object2IntArrayMap<>(16);
|
||||
|
||||
static {
|
||||
NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.BLACK, 0);
|
||||
NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.DARK_BLUE, 1);
|
||||
@ -102,9 +102,9 @@ public class AdventurePacketConvertor {
|
||||
* Creates a sound packet from a sound and a location.
|
||||
*
|
||||
* @param sound the sound
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
* @return the sound packet
|
||||
*/
|
||||
public static @NotNull ServerPacket createSoundPacket(@NotNull Sound sound, double x, double y, double z) {
|
||||
@ -136,7 +136,7 @@ public class AdventurePacketConvertor {
|
||||
/**
|
||||
* Creates a sound effect packet from a sound and an emitter.
|
||||
*
|
||||
* @param sound the sound
|
||||
* @param sound the sound
|
||||
* @param emitter the emitter, must be an {@link Entity}
|
||||
* @return the sound packet
|
||||
*/
|
||||
@ -158,14 +158,13 @@ public class AdventurePacketConvertor {
|
||||
packet.pitch = sound.pitch();
|
||||
return packet;
|
||||
} else {
|
||||
final Position pos = entity.getPosition();
|
||||
|
||||
final var pos = entity.getPosition();
|
||||
final NamedSoundEffectPacket packet = new NamedSoundEffectPacket();
|
||||
packet.soundName = sound.name().asString();
|
||||
packet.soundSource = sound.source();
|
||||
packet.x = (int) pos.getX();
|
||||
packet.y = (int) pos.getY();
|
||||
packet.z = (int) pos.getX();
|
||||
packet.x = (int) pos.x();
|
||||
packet.y = (int) pos.y();
|
||||
packet.z = (int) pos.z();
|
||||
packet.volume = sound.volume();
|
||||
packet.pitch = sound.pitch();
|
||||
return packet;
|
||||
@ -175,7 +174,7 @@ public class AdventurePacketConvertor {
|
||||
/**
|
||||
* Creates an entity sound packet from an Adventure sound.
|
||||
*
|
||||
* @param sound the sound
|
||||
* @param sound the sound
|
||||
* @param entity the entity the sound is coming from
|
||||
* @return the packet
|
||||
* @deprecated Use {@link #createSoundPacket(Sound, Sound.Emitter)}
|
||||
|
@ -150,7 +150,7 @@ public class BoundingBox {
|
||||
* @return the min X
|
||||
*/
|
||||
public double getMinX() {
|
||||
return entity.getPosition().getX() - (x / 2);
|
||||
return entity.getPosition().x() - (x / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,7 +159,7 @@ public class BoundingBox {
|
||||
* @return the max X
|
||||
*/
|
||||
public double getMaxX() {
|
||||
return entity.getPosition().getX() + (x / 2);
|
||||
return entity.getPosition().x() + (x / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,7 +168,7 @@ public class BoundingBox {
|
||||
* @return the min Y
|
||||
*/
|
||||
public double getMinY() {
|
||||
return entity.getPosition().getY();
|
||||
return entity.getPosition().y();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,7 +177,7 @@ public class BoundingBox {
|
||||
* @return the max Y
|
||||
*/
|
||||
public double getMaxY() {
|
||||
return entity.getPosition().getY() + y;
|
||||
return entity.getPosition().y() + y;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +186,7 @@ public class BoundingBox {
|
||||
* @return the min Z
|
||||
*/
|
||||
public double getMinZ() {
|
||||
return entity.getPosition().getZ() - (z / 2);
|
||||
return entity.getPosition().z() - (z / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,7 +195,7 @@ public class BoundingBox {
|
||||
* @return the max Z
|
||||
*/
|
||||
public double getMaxZ() {
|
||||
return entity.getPosition().getZ() + (z / 2);
|
||||
return entity.getPosition().z() + (z / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,6 +9,8 @@ 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.coordinate.Point;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CollisionUtils {
|
||||
@ -190,8 +192,8 @@ public class CollisionUtils {
|
||||
* @return the position with the world border collision applied (can be {@code newPosition} if not changed)
|
||||
*/
|
||||
@NotNull
|
||||
public static Position applyWorldBorder(@NotNull Instance instance,
|
||||
@NotNull Position currentPosition, @NotNull Position newPosition) {
|
||||
public static Point applyWorldBorder(@NotNull Instance instance,
|
||||
@NotNull Point currentPosition, @NotNull Point newPosition) {
|
||||
final WorldBorder worldBorder = instance.getWorldBorder();
|
||||
final WorldBorder.CollisionAxis collisionAxis = worldBorder.getCollisionAxis(newPosition);
|
||||
switch (collisionAxis) {
|
||||
@ -200,13 +202,13 @@ public class CollisionUtils {
|
||||
return newPosition;
|
||||
case BOTH:
|
||||
// Apply Y velocity/gravity
|
||||
return new Position(currentPosition.getX(), newPosition.getY(), currentPosition.getZ());
|
||||
return new Vec(currentPosition.x(), newPosition.y(), currentPosition.z());
|
||||
case X:
|
||||
// Apply Y/Z velocity/gravity
|
||||
return new Position(currentPosition.getX(), newPosition.getY(), newPosition.getZ());
|
||||
return new Vec(currentPosition.x(), newPosition.y(), newPosition.z());
|
||||
case Z:
|
||||
// Apply X/Y velocity/gravity
|
||||
return new Position(newPosition.getX(), newPosition.getY(), currentPosition.getZ());
|
||||
return new Vec(newPosition.x(), newPosition.y(), currentPosition.z());
|
||||
}
|
||||
throw new IllegalStateException("Something weird happened...");
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.callback.OptionalCallback;
|
||||
import net.minestom.server.utils.chunk.ChunkCallback;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
import net.minestom.server.utils.entity.EntityUtils;
|
||||
import net.minestom.server.utils.player.PlayerUtils;
|
||||
@ -77,16 +79,8 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
|
||||
protected Instance instance;
|
||||
protected Chunk currentChunk;
|
||||
protected final Position position;
|
||||
/**
|
||||
* Used to calculate delta movement
|
||||
*/
|
||||
protected final Position lastPosition;
|
||||
/**
|
||||
* Used to check if any change made to the {@link Entity#position} field since
|
||||
* the last packets sent
|
||||
*/
|
||||
protected final Position lastSyncedPosition;
|
||||
protected Pos position;
|
||||
protected Pos lastSyncedPosition;
|
||||
protected boolean onGround;
|
||||
|
||||
private BoundingBox boundingBox;
|
||||
@ -94,7 +88,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
protected Entity vehicle;
|
||||
|
||||
// Velocity
|
||||
protected Vector velocity = new Vector(); // Movement in block per second
|
||||
protected Vec velocity = Vec.ZERO; // Movement in block per second
|
||||
protected boolean hasPhysics = true;
|
||||
|
||||
/**
|
||||
@ -159,9 +153,8 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
this.id = generateId();
|
||||
this.entityType = entityType;
|
||||
this.uuid = uuid;
|
||||
this.position = new Position();
|
||||
this.lastPosition = new Position();
|
||||
this.lastSyncedPosition = new Position();
|
||||
this.position = Pos.ZERO;
|
||||
this.lastSyncedPosition = Pos.ZERO;
|
||||
|
||||
setBoundingBox(entityType.getWidth(), entityType.getHeight(), entityType.getWidth());
|
||||
|
||||
@ -181,18 +174,6 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
this(entityType, UUID.randomUUID());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Entity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) {
|
||||
this(entityType, uuid);
|
||||
this.position.set(spawnPosition);
|
||||
this.lastPosition.set(spawnPosition);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Entity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
|
||||
this(entityType, UUID.randomUUID(), spawnPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a task to be run during the next entity tick.
|
||||
* It ensures that the task will be executed in the same thread as the entity (depending of the {@link ThreadProvider}).
|
||||
@ -281,31 +262,26 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
* @param callback the optional callback executed, even if auto chunk is not enabled
|
||||
* @throws IllegalStateException if you try to teleport an entity before settings its instance
|
||||
*/
|
||||
public void teleport(@NotNull Position position, @Nullable long[] chunks, @Nullable Runnable callback) {
|
||||
public void teleport(@NotNull Pos position, @Nullable long[] chunks, @Nullable Runnable callback) {
|
||||
Check.stateCondition(instance == null, "You need to use Entity#setInstance before teleporting an entity!");
|
||||
|
||||
final Position teleportPosition = position.clone(); // Prevent synchronization issue
|
||||
|
||||
final ChunkCallback endCallback = (chunk) -> {
|
||||
refreshPosition(teleportPosition);
|
||||
|
||||
refreshPosition(position);
|
||||
synchronizePosition(true);
|
||||
|
||||
OptionalCallback.execute(callback);
|
||||
};
|
||||
|
||||
if (chunks == null || chunks.length == 0) {
|
||||
instance.loadOptionalChunk(teleportPosition, endCallback);
|
||||
instance.loadOptionalChunk(position, endCallback);
|
||||
} else {
|
||||
ChunkUtils.optionalLoadAll(instance, chunks, null, endCallback);
|
||||
}
|
||||
}
|
||||
|
||||
public void teleport(@NotNull Position position, @Nullable Runnable callback) {
|
||||
public void teleport(@NotNull Pos position, @Nullable Runnable callback) {
|
||||
teleport(position, null, callback);
|
||||
}
|
||||
|
||||
public void teleport(@NotNull Position position) {
|
||||
public void teleport(@NotNull Pos position) {
|
||||
teleport(position, null);
|
||||
}
|
||||
|
||||
@ -316,7 +292,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
* @param pitch the new pitch
|
||||
*/
|
||||
public void setView(float yaw, float pitch) {
|
||||
refreshView(yaw, pitch);
|
||||
this.position = position.withView(yaw, pitch);
|
||||
|
||||
EntityRotationPacket entityRotationPacket = new EntityRotationPacket();
|
||||
entityRotationPacket.entityId = getEntityId();
|
||||
@ -396,7 +372,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
{
|
||||
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
||||
entityHeadLookPacket.entityId = getEntityId();
|
||||
entityHeadLookPacket.yaw = position.getYaw();
|
||||
entityHeadLookPacket.yaw = position.yaw();
|
||||
playerConnection.sendPacket(entityHeadLookPacket);
|
||||
}
|
||||
|
||||
@ -532,9 +508,9 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
|
||||
if (applyVelocity) {
|
||||
final float tps = MinecraftServer.TICK_PER_SECOND;
|
||||
final double newX = position.getX() + velocity.getX() / tps;
|
||||
final double newY = position.getY() + velocity.getY() / tps;
|
||||
final double newZ = position.getZ() + velocity.getZ() / tps;
|
||||
final double newX = position.x() + velocity.x() / tps;
|
||||
final double newY = position.y() + velocity.y() / tps;
|
||||
final double newZ = position.z() + velocity.z() / tps;
|
||||
Position newPosition = new Position(newX, newY, newZ);
|
||||
|
||||
Vector newVelocityOut = new Vector();
|
||||
@ -555,7 +531,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
}
|
||||
|
||||
// World border collision
|
||||
final Position finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition);
|
||||
final Point finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition);
|
||||
final Chunk finalChunk = ChunkUtils.retrieve(instance, currentChunk, finalVelocityPosition);
|
||||
if (!ChunkUtils.isLoaded(finalChunk)) {
|
||||
// Entity shouldn't be updated when moving in an unloaded chunk
|
||||
@ -563,20 +539,17 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
}
|
||||
|
||||
// Apply the position if changed
|
||||
if (!finalVelocityPosition.isSimilar(position)) {
|
||||
refreshPosition(finalVelocityPosition.getX(),
|
||||
finalVelocityPosition.getY(),
|
||||
finalVelocityPosition.getZ());
|
||||
if (!finalVelocityPosition.samePoint(position)) {
|
||||
refreshCoordinate(finalVelocityPosition);
|
||||
sendPositionUpdate(true);
|
||||
}
|
||||
|
||||
|
||||
// Update velocity
|
||||
if (hasVelocity() || !newVelocityOut.isZero()) {
|
||||
this.velocity.copy(newVelocityOut);
|
||||
this.velocity.multiply(tps);
|
||||
|
||||
final Block block = finalChunk.getBlock(position.toBlockPosition());
|
||||
final Block block = finalChunk.getBlock(position);
|
||||
final double drag = block.registry().friction();
|
||||
if (onGround) {
|
||||
// Stop player velocity
|
||||
@ -686,10 +659,10 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
* @param clientSide {@code true} if the client triggered this action
|
||||
*/
|
||||
protected void sendPositionUpdate(final boolean clientSide) {
|
||||
final boolean viewChange = !position.hasSimilarView(lastSyncedPosition);
|
||||
final double distanceX = Math.abs(position.getX() - lastSyncedPosition.getX());
|
||||
final double distanceY = Math.abs(position.getY() - lastSyncedPosition.getY());
|
||||
final double distanceZ = Math.abs(position.getZ() - lastSyncedPosition.getZ());
|
||||
final boolean viewChange = !position.sameView(lastSyncedPosition);
|
||||
final double distanceX = Math.abs(position.x() - lastSyncedPosition.x());
|
||||
final double distanceY = Math.abs(position.y() - lastSyncedPosition.y());
|
||||
final double distanceZ = Math.abs(position.z() - lastSyncedPosition.z());
|
||||
final boolean positionChange = (distanceX + distanceY + distanceZ) > 0;
|
||||
|
||||
if (distanceX > 8 || distanceY > 8 || distanceZ > 8) {
|
||||
@ -704,7 +677,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
// Fix head rotation
|
||||
final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
||||
entityHeadLookPacket.entityId = getEntityId();
|
||||
entityHeadLookPacket.yaw = position.getYaw();
|
||||
entityHeadLookPacket.yaw = position.yaw();
|
||||
sendPacketToViewersAndSelf(entityHeadLookPacket);
|
||||
} else if (positionChange) {
|
||||
final EntityPositionPacket entityPositionPacket = EntityPositionPacket
|
||||
@ -713,13 +686,13 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
} else if (viewChange) {
|
||||
final EntityRotationPacket entityRotationPacket = new EntityRotationPacket();
|
||||
entityRotationPacket.entityId = getEntityId();
|
||||
entityRotationPacket.yaw = position.getYaw();
|
||||
entityRotationPacket.pitch = position.getPitch();
|
||||
entityRotationPacket.yaw = position.yaw();
|
||||
entityRotationPacket.pitch = position.pitch();
|
||||
entityRotationPacket.onGround = onGround;
|
||||
|
||||
final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
||||
entityHeadLookPacket.entityId = getEntityId();
|
||||
entityHeadLookPacket.yaw = position.getYaw();
|
||||
entityHeadLookPacket.yaw = position.yaw();
|
||||
|
||||
if (clientSide) {
|
||||
sendPacketToViewers(entityHeadLookPacket);
|
||||
@ -736,12 +709,12 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
if (PlayerUtils.isNettyClient(this) && !clientSide) {
|
||||
final PlayerPositionAndLookPacket playerPositionAndLookPacket = new PlayerPositionAndLookPacket();
|
||||
playerPositionAndLookPacket.flags = 0b111;
|
||||
playerPositionAndLookPacket.position = position.clone().subtract(lastSyncedPosition.getX(), lastSyncedPosition.getY(), lastSyncedPosition.getZ());
|
||||
playerPositionAndLookPacket.position = position.sub(lastSyncedPosition);
|
||||
playerPositionAndLookPacket.teleportId = ((Player) this).getNextTeleportId();
|
||||
((Player) this).getPlayerConnection().sendPacket(playerPositionAndLookPacket);
|
||||
}
|
||||
|
||||
lastSyncedPosition.set(position);
|
||||
this.lastSyncedPosition = position;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -893,25 +866,25 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
* @param spawnPosition the spawn position for the entity.
|
||||
* @throws IllegalStateException if {@code instance} has not been registered in {@link InstanceManager}
|
||||
*/
|
||||
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
|
||||
public void setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) {
|
||||
Check.stateCondition(!instance.isRegistered(),
|
||||
"Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance");
|
||||
|
||||
if (this.instance != null) {
|
||||
this.instance.UNSAFE_removeEntity(this);
|
||||
}
|
||||
|
||||
this.position.set(spawnPosition);
|
||||
this.lastPosition.set(position);
|
||||
|
||||
this.position = spawnPosition;
|
||||
this.isActive = true;
|
||||
this.instance = instance;
|
||||
refreshCurrentChunk(instance.getChunkAt(position.getX(), position.getZ()));
|
||||
refreshCurrentChunk(instance.getChunkAt(position));
|
||||
instance.UNSAFE_addEntity(this);
|
||||
spawn();
|
||||
EventDispatcher.call(new EntitySpawnEvent(this, instance));
|
||||
}
|
||||
|
||||
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
|
||||
setInstance(instance, Pos.fromPosition(spawnPosition));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the entity instance.
|
||||
*
|
||||
@ -928,8 +901,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
*
|
||||
* @return the entity current velocity
|
||||
*/
|
||||
@NotNull
|
||||
public Vector getVelocity() {
|
||||
public @NotNull Vec getVelocity() {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
@ -940,10 +912,10 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
*
|
||||
* @param velocity the new entity velocity
|
||||
*/
|
||||
public void setVelocity(@NotNull Vector velocity) {
|
||||
public void setVelocity(@NotNull Vec velocity) {
|
||||
EntityVelocityEvent entityVelocityEvent = new EntityVelocityEvent(this, velocity);
|
||||
EventDispatcher.callCancellable(entityVelocityEvent, () -> {
|
||||
this.velocity.copy(entityVelocityEvent.getVelocity());
|
||||
this.velocity = entityVelocityEvent.getVelocity();
|
||||
sendPacketToViewersAndSelf(getVelocityPacket());
|
||||
});
|
||||
}
|
||||
@ -954,7 +926,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
* @return true if velocity is not set to 0
|
||||
*/
|
||||
public boolean hasVelocity() {
|
||||
return !velocity.isZero();
|
||||
return !velocity.samePoint(Vec.ZERO);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1003,7 +975,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
* @return the distance between this and {@code entity}
|
||||
*/
|
||||
public double getDistance(@NotNull Entity entity) {
|
||||
return getPosition().getDistance(entity.getPosition());
|
||||
return getPosition().distance(entity.getPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1013,7 +985,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
* @return the distance squared between this and {@code entity}
|
||||
*/
|
||||
public double getDistanceSquared(@NotNull Entity entity) {
|
||||
return getPosition().getDistanceSquared(entity.getPosition());
|
||||
return getPosition().distanceSquared(entity.getPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1321,42 +1293,57 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
this.entityMeta.setHasNoGravity(noGravity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates internal fields and sends updates
|
||||
*
|
||||
* @param position the new position
|
||||
* @see #refreshCoordinate(Pos)
|
||||
* @see #sendPositionUpdate(boolean)
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void refreshPosition(@NotNull final Pos position, boolean ignoreView) {
|
||||
if (!ignoreView) {
|
||||
this.position = position;
|
||||
} else {
|
||||
this.position = this.position.withCoord(position);
|
||||
}
|
||||
if (!position.samePoint(this.position)) {
|
||||
refreshCoordinate(position);
|
||||
}
|
||||
sendPositionUpdate(true);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public void refreshPosition(@NotNull final Pos position) {
|
||||
refreshPosition(position, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to refresh the entity and its passengers position
|
||||
* - put the entity in the right instance chunk
|
||||
* - update the viewable chunks (load and unload)
|
||||
* - add/remove players from the viewers list if {@link #isAutoViewable()} is enabled
|
||||
* <p>
|
||||
* WARNING: unsafe, should only be used internally in Minestom. Use {@link #teleport(Position)} instead.
|
||||
* WARNING: unsafe, should only be used internally in Minestom. Use {@link #teleport(Pos)} instead.
|
||||
*
|
||||
* @param x new position X
|
||||
* @param y new position Y
|
||||
* @param z new position Z
|
||||
* @param newPosition the new position
|
||||
*/
|
||||
private void refreshPosition(double x, double y, double z) {
|
||||
position.setX(x);
|
||||
position.setY(y);
|
||||
position.setZ(z);
|
||||
|
||||
private void refreshCoordinate(Point newPosition) {
|
||||
if (hasPassenger()) {
|
||||
for (Entity passenger : getPassengers()) {
|
||||
passenger.refreshPosition(x, y, z);
|
||||
passenger.refreshCoordinate(newPosition);
|
||||
}
|
||||
}
|
||||
|
||||
final Instance instance = getInstance();
|
||||
if (instance != null) {
|
||||
final int lastChunkX = currentChunk.getChunkX();
|
||||
final int lastChunkZ = currentChunk.getChunkZ();
|
||||
|
||||
final int newChunkX = ChunkUtils.getChunkCoordinate(x);
|
||||
final int newChunkZ = ChunkUtils.getChunkCoordinate(z);
|
||||
|
||||
final int newChunkX = ChunkUtils.getChunkCoordinate(newPosition.x());
|
||||
final int newChunkZ = ChunkUtils.getChunkCoordinate(newPosition.z());
|
||||
if (lastChunkX != newChunkX || lastChunkZ != newChunkZ) {
|
||||
// Entity moved in a new chunk
|
||||
final Chunk newChunk = instance.getChunk(newChunkX, newChunkZ);
|
||||
Check.notNull(newChunk, "The entity {0} tried to move in an unloaded chunk at {1};{2}", getEntityId(), x, z);
|
||||
|
||||
Check.notNull(newChunk, "The entity {0} tried to move in an unloaded chunk at {1}", getEntityId(), newPosition);
|
||||
instance.UNSAFE_switchEntityChunk(this, currentChunk, newChunk);
|
||||
if (this instanceof Player) {
|
||||
// Refresh player view
|
||||
@ -1364,45 +1351,10 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
player.refreshVisibleChunks(newChunk);
|
||||
player.refreshVisibleEntities(newChunk);
|
||||
}
|
||||
|
||||
refreshCurrentChunk(newChunk);
|
||||
}
|
||||
}
|
||||
|
||||
this.lastPosition.setX(position.getX());
|
||||
this.lastPosition.setY(position.getY());
|
||||
this.lastPosition.setZ(position.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates internal fields and sends updates
|
||||
*
|
||||
* @param position the new position
|
||||
* @see #refreshPosition(double, double, double)
|
||||
* @see #refreshView(float, float)
|
||||
* @see #sendPositionUpdate(boolean)
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void refreshPosition(@NotNull final Position position) {
|
||||
if (!position.isSimilar(this.position))
|
||||
refreshPosition(position.getX(), position.getY(), position.getZ());
|
||||
refreshView(position.getYaw(), position.getPitch());
|
||||
sendPositionUpdate(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the entity view internally.
|
||||
* <p>
|
||||
* Warning: you probably want to use {@link #setView(float, float)}.
|
||||
*
|
||||
* @param yaw the yaw
|
||||
* @param pitch the pitch
|
||||
*/
|
||||
private void refreshView(final float yaw, final float pitch) {
|
||||
lastPosition.setYaw(position.getYaw());
|
||||
lastPosition.setPitch(position.getPitch());
|
||||
position.setYaw(yaw);
|
||||
position.setPitch(pitch);
|
||||
this.lastPosition = position;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1410,8 +1362,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
*
|
||||
* @return the current position of the entity
|
||||
*/
|
||||
@NotNull
|
||||
public Position getPosition() {
|
||||
public @NotNull Pos getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@ -1536,19 +1487,17 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
return scheduledRemoveTime != 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Vector getVelocityForPacket() {
|
||||
return this.velocity.clone().multiply(8000f / MinecraftServer.TICK_PER_SECOND);
|
||||
protected @NotNull Vec getVelocityForPacket() {
|
||||
return this.velocity.mul(8000f / MinecraftServer.TICK_PER_SECOND);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected EntityVelocityPacket getVelocityPacket() {
|
||||
protected @NotNull EntityVelocityPacket getVelocityPacket() {
|
||||
EntityVelocityPacket velocityPacket = new EntityVelocityPacket();
|
||||
velocityPacket.entityId = getEntityId();
|
||||
Vector velocity = getVelocityForPacket();
|
||||
velocityPacket.velocityX = (short) velocity.getX();
|
||||
velocityPacket.velocityY = (short) velocity.getY();
|
||||
velocityPacket.velocityZ = (short) velocity.getZ();
|
||||
Vec velocity = getVelocityForPacket();
|
||||
velocityPacket.velocityX = (short) velocity.x();
|
||||
velocityPacket.velocityY = (short) velocity.y();
|
||||
velocityPacket.velocityZ = (short) velocity.z();
|
||||
return velocityPacket;
|
||||
}
|
||||
|
||||
@ -1576,15 +1525,14 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
protected void synchronizePosition(boolean includeSelf) {
|
||||
final Position pos = position.clone();
|
||||
final EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket();
|
||||
entityTeleportPacket.entityId = getEntityId();
|
||||
entityTeleportPacket.position = pos;
|
||||
entityTeleportPacket.position = position;
|
||||
entityTeleportPacket.onGround = isOnGround();
|
||||
sendPacketToViewers(entityTeleportPacket);
|
||||
|
||||
this.lastAbsoluteSynchronizationTime = System.currentTimeMillis();
|
||||
this.lastSyncedPosition.set(pos);
|
||||
this.lastSyncedPosition = position;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1738,10 +1686,13 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
public void takeKnockback(final float strength, final double x, final double z) {
|
||||
if (strength > 0) {
|
||||
//TODO check possible side effects of unnatural TPS (other than 20TPS)
|
||||
final Vector velocityModifier = new Vector(x, 0d, z).normalize().multiply(strength * MinecraftServer.TICK_PER_SECOND / 2);
|
||||
this.velocity.setX(velocity.getX() / 2d - velocityModifier.getX());
|
||||
this.velocity.setY(onGround ? Math.min(.4d, velocity.getY() / 2d + strength) * MinecraftServer.TICK_PER_SECOND : velocity.getY());
|
||||
this.velocity.setZ(velocity.getZ() / 2d - velocityModifier.getZ());
|
||||
final Vec velocityModifier = new Vec(x, z)
|
||||
.normalize()
|
||||
.mul(strength * MinecraftServer.TICK_PER_SECOND / 2);
|
||||
setVelocity(new Vec(velocity.x() / 2d - velocityModifier.x(),
|
||||
onGround ? Math.min(.4d, velocity.y() / 2d + strength) * MinecraftServer.TICK_PER_SECOND : velocity.y(),
|
||||
velocity.z() / 2d - velocityModifier.z()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,20 +42,6 @@ public class EntityCreature extends LivingEntity implements NavigableEntity, Ent
|
||||
this(entityType, UUID.randomUUID());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public EntityCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
|
||||
super(entityType, spawnPosition);
|
||||
heal();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public EntityCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition, @Nullable Instance instance) {
|
||||
this(entityType, spawnPosition);
|
||||
if (instance != null) {
|
||||
setInstance(instance);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long time) {
|
||||
// AI
|
||||
|
@ -1,8 +1,5 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.LivingEntity;
|
||||
import net.minestom.server.entity.metadata.ProjectileMeta;
|
||||
import net.minestom.server.event.EventDispatcher;
|
||||
import net.minestom.server.event.entity.EntityAttackEvent;
|
||||
@ -13,6 +10,8 @@ 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.coordinate.Point;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -35,13 +34,6 @@ public class EntityProjectile extends Entity {
|
||||
setup();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public EntityProjectile(@Nullable Entity shooter, @NotNull EntityType entityType, @NotNull Position spawnPosition) {
|
||||
super(entityType, spawnPosition);
|
||||
this.shooter = shooter;
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
super.hasPhysics = false;
|
||||
if (getEntityMeta() instanceof ProjectileMeta) {
|
||||
@ -70,21 +62,21 @@ public class EntityProjectile extends Entity {
|
||||
|
||||
}
|
||||
|
||||
public void shoot(Position to, double power, double spread) {
|
||||
public void shoot(Point to, double power, double spread) {
|
||||
EntityShootEvent shootEvent = new EntityShootEvent(this.shooter, this, to, power, spread);
|
||||
EventDispatcher.call(shootEvent);
|
||||
if (shootEvent.isCancelled()) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
Position from = this.shooter.getPosition().clone().add(0D, this.shooter.getEyeHeight(), 0D);
|
||||
final var from = this.shooter.getPosition().add(0D, this.shooter.getEyeHeight(), 0D);
|
||||
shoot(from, to, shootEvent.getPower(), shootEvent.getSpread());
|
||||
}
|
||||
|
||||
private void shoot(@NotNull Position from, @NotNull Position to, double power, double spread) {
|
||||
double dx = to.getX() - from.getX();
|
||||
double dy = to.getY() - from.getY();
|
||||
double dz = to.getZ() - from.getZ();
|
||||
private void shoot(@NotNull Point from, @NotNull Point to, double power, double spread) {
|
||||
double dx = to.x() - from.x();
|
||||
double dy = to.y() - from.y();
|
||||
double dz = to.z() - from.z();
|
||||
double xzLength = Math.sqrt(dx * dx + dz * dz);
|
||||
dy += xzLength * 0.20000000298023224D;
|
||||
|
||||
@ -97,10 +89,9 @@ public class EntityProjectile extends Entity {
|
||||
dx += random.nextGaussian() * spread;
|
||||
dy += random.nextGaussian() * spread;
|
||||
dz += random.nextGaussian() * spread;
|
||||
super.velocity.setX(dx);
|
||||
super.velocity.setY(dy);
|
||||
super.velocity.setZ(dz);
|
||||
super.velocity.multiply(20 * power);
|
||||
|
||||
final double mul = 20 * power;
|
||||
this.velocity = new Vec(dx * mul, dy * mul, dz * mul);
|
||||
setView(
|
||||
(float) Math.toDegrees(Math.atan2(dx, dz)),
|
||||
(float) Math.toDegrees(Math.atan2(dy, Math.sqrt(dx * dx + dz * dz)))
|
||||
@ -109,15 +100,15 @@ public class EntityProjectile extends Entity {
|
||||
|
||||
@Override
|
||||
public void tick(long time) {
|
||||
Position posBefore = getPosition().clone();
|
||||
final var posBefore = getPosition();
|
||||
super.tick(time);
|
||||
Position posNow = getPosition().clone();
|
||||
final var posNow = getPosition();
|
||||
if (isStuck(posBefore, posNow)) {
|
||||
if (super.onGround) {
|
||||
return;
|
||||
}
|
||||
super.onGround = true;
|
||||
getVelocity().zero();
|
||||
this.velocity = Vec.ZERO;
|
||||
sendPacketToViewersAndSelf(getVelocityPacket());
|
||||
setNoGravity(true);
|
||||
onStuck();
|
||||
@ -139,8 +130,8 @@ public class EntityProjectile extends Entity {
|
||||
* @return if an arrow is stuck in block / hit an entity.
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private boolean isStuck(Position pos, Position posNow) {
|
||||
if (pos.isSimilar(posNow)) {
|
||||
private boolean isStuck(Point pos, Point posNow) {
|
||||
if (pos.samePoint(posNow)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -200,5 +191,4 @@ public class EntityProjectile extends Entity {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,10 +21,10 @@ public enum EntitySpawnType {
|
||||
ObjectDataProvider objectDataProvider = (ObjectDataProvider) entity.getEntityMeta();
|
||||
packet.data = objectDataProvider.getObjectData();
|
||||
if (objectDataProvider.requiresVelocityPacketAtSpawn()) {
|
||||
Vector velocity = entity.getVelocityForPacket();
|
||||
packet.velocityX = (short) velocity.getX();
|
||||
packet.velocityY = (short) velocity.getY();
|
||||
packet.velocityZ = (short) velocity.getZ();
|
||||
final var velocity = entity.getVelocityForPacket();
|
||||
packet.velocityX = (short) velocity.x();
|
||||
packet.velocityY = (short) velocity.y();
|
||||
packet.velocityZ = (short) velocity.z();
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
@ -38,11 +38,11 @@ public enum EntitySpawnType {
|
||||
packet.entityUuid = entity.getUuid();
|
||||
packet.entityType = entity.getEntityType().ordinal();
|
||||
packet.position = entity.getPosition();
|
||||
packet.headPitch = entity.getPosition().getPitch();
|
||||
Vector velocity = entity.getVelocityForPacket();
|
||||
packet.velocityX = (short) velocity.getX();
|
||||
packet.velocityY = (short) velocity.getY();
|
||||
packet.velocityZ = (short) velocity.getZ();
|
||||
packet.headPitch = entity.getPosition().pitch();
|
||||
final var velocity = entity.getVelocityForPacket();
|
||||
packet.velocityX = (short) velocity.x();
|
||||
packet.velocityY = (short) velocity.y();
|
||||
packet.velocityZ = (short) velocity.z();
|
||||
return packet;
|
||||
}
|
||||
},
|
||||
|
@ -1,10 +1,6 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
@ -14,22 +10,13 @@ public class ExperienceOrb extends Entity {
|
||||
private Player target;
|
||||
private long lastTargetUpdateTick;
|
||||
|
||||
|
||||
public ExperienceOrb(short experienceCount, @NotNull Position spawnPosition) {
|
||||
super(EntityType.EXPERIENCE_ORB, spawnPosition);
|
||||
public ExperienceOrb(short experienceCount) {
|
||||
super(EntityType.EXPERIENCE_ORB);
|
||||
setBoundingBox(0.5f, 0.5f, 0.5f);
|
||||
//todo vanilla sets random velocity here?
|
||||
this.experienceCount = experienceCount;
|
||||
}
|
||||
|
||||
public ExperienceOrb(short experienceCount, @NotNull Position spawnPosition, @Nullable Instance instance) {
|
||||
this(experienceCount, spawnPosition);
|
||||
|
||||
if (instance != null) {
|
||||
setInstance(instance);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long time) {
|
||||
|
||||
@ -44,7 +31,7 @@ public class ExperienceOrb extends Entity {
|
||||
|
||||
double d = 8.0;
|
||||
if (lastTargetUpdateTick < time - 20 + getEntityId() % 100) {
|
||||
if (target == null || target.getPosition().getDistanceSquared(getPosition()) > 64) {
|
||||
if (target == null || target.getPosition().distanceSquared(getPosition()) > 64) {
|
||||
this.target = getClosestPlayer(this, 8);
|
||||
}
|
||||
|
||||
@ -56,13 +43,13 @@ public class ExperienceOrb extends Entity {
|
||||
}
|
||||
|
||||
if (target != null) {
|
||||
Position pos = getPosition();
|
||||
Position targetPos = target.getPosition();
|
||||
Vector toTarget = new Vector(targetPos.getX() - pos.getX(), targetPos.getY() + (target.getEyeHeight() / 2) - pos.getY(), targetPos.getZ() - pos.getZ());
|
||||
final var pos = getPosition();
|
||||
final var targetPos = target.getPosition();
|
||||
final Vec toTarget = new Vec(targetPos.x() - pos.x(), targetPos.y() + (target.getEyeHeight() / 2) - pos.y(), targetPos.z() - pos.z());
|
||||
double e = toTarget.length(); //could really be lengthSquared
|
||||
if (e < 8) {
|
||||
double f = 1 - (e / 8);
|
||||
setVelocity(getVelocity().add(toTarget.normalize().multiply(f * f * 0.1)));
|
||||
setVelocity(getVelocity().add(toTarget.normalize().mul(f * f * 0.1)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,9 +61,10 @@ public class ExperienceOrb extends Entity {
|
||||
}
|
||||
// apply slipperiness
|
||||
|
||||
setVelocity(getVelocity().multiply(new Vector(g, 0.98f, g)));
|
||||
if (isOnGround())
|
||||
setVelocity(getVelocity().multiply(new Vector(1, -0.9f, 1)));
|
||||
setVelocity(getVelocity().mul(new Vec(g, 0.98f, g)));
|
||||
if (isOnGround()) {
|
||||
setVelocity(getVelocity().mul(new Vec(1, -0.9f, 1)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4,10 +4,8 @@ import net.minestom.server.entity.metadata.item.ItemEntityMeta;
|
||||
import net.minestom.server.event.EventDispatcher;
|
||||
import net.minestom.server.event.entity.EntityItemMergeEvent;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.StackingRule;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -41,20 +39,12 @@ public class ItemEntity extends Entity {
|
||||
private long spawnTime;
|
||||
private long pickupDelay;
|
||||
|
||||
public ItemEntity(@NotNull ItemStack itemStack, @NotNull Position spawnPosition) {
|
||||
super(EntityType.ITEM, spawnPosition);
|
||||
public ItemEntity(@NotNull ItemStack itemStack) {
|
||||
super(EntityType.ITEM);
|
||||
setItemStack(itemStack);
|
||||
setBoundingBox(0.25f, 0.25f, 0.25f);
|
||||
}
|
||||
|
||||
public ItemEntity(@NotNull ItemStack itemStack, @NotNull Position spawnPosition, @Nullable Instance instance) {
|
||||
this(itemStack, spawnPosition);
|
||||
|
||||
if (instance != null) {
|
||||
setInstance(instance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the update option for the merging feature.
|
||||
*
|
||||
@ -70,7 +60,6 @@ public class ItemEntity extends Entity {
|
||||
* Can be set to null to entirely remove the delay.
|
||||
*
|
||||
* @param mergeUpdateOption the new merge update option
|
||||
*
|
||||
* @deprecated Replaced by {@link #setMergeDelay(Duration)}
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@ -239,7 +228,7 @@ public class ItemEntity extends Entity {
|
||||
/**
|
||||
* Sets the pickup delay of the ItemEntity.
|
||||
*
|
||||
* @param delay the pickup delay
|
||||
* @param delay the pickup delay
|
||||
* @param temporalUnit the unit of the delay
|
||||
*/
|
||||
public void setPickupDelay(long delay, @NotNull TemporalUnit temporalUnit) {
|
||||
@ -249,7 +238,7 @@ public class ItemEntity extends Entity {
|
||||
/**
|
||||
* Sets the pickup delay of the ItemEntity.
|
||||
*
|
||||
* @param delay the pickup delay
|
||||
* @param delay the pickup delay
|
||||
*/
|
||||
public void setPickupDelay(Duration delay) {
|
||||
this.pickupDelay = delay.toMillis();
|
||||
|
@ -26,9 +26,9 @@ import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.scoreboard.Team;
|
||||
import net.minestom.server.sound.SoundEvent;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.block.BlockIterator;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -90,7 +90,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
|
||||
* Constructor which allows to specify an UUID. Only use if you know what you are doing!
|
||||
*/
|
||||
public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid) {
|
||||
this(entityType, uuid, new Position());
|
||||
super(entityType, uuid);
|
||||
initEquipments();
|
||||
}
|
||||
|
||||
@ -98,20 +98,6 @@ public class LivingEntity extends Entity implements EquipmentHandler {
|
||||
this(entityType, UUID.randomUUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor which allows to specify an UUID. Only use if you know what you are doing!
|
||||
*/
|
||||
@Deprecated
|
||||
public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) {
|
||||
super(entityType, uuid, spawnPosition);
|
||||
initEquipments();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public LivingEntity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
|
||||
this(entityType, UUID.randomUUID(), spawnPosition);
|
||||
}
|
||||
|
||||
private void initEquipments() {
|
||||
this.mainHandItem = ItemStack.AIR;
|
||||
this.offHandItem = ItemStack.AIR;
|
||||
@ -300,7 +286,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
|
||||
setHealth(0);
|
||||
|
||||
// Reset velocity
|
||||
velocity.zero();
|
||||
this.velocity = Vec.ZERO;
|
||||
|
||||
// Remove passengers if any
|
||||
if (hasPassenger()) {
|
||||
@ -323,8 +309,8 @@ public class LivingEntity extends Entity implements EquipmentHandler {
|
||||
/**
|
||||
* Sets fire to this entity for a given duration.
|
||||
*
|
||||
* @param duration duration of the effect
|
||||
* @param temporalUnit unit used to express the duration
|
||||
* @param duration duration of the effect
|
||||
* @param temporalUnit unit used to express the duration
|
||||
* @see #setOnFire(boolean) if you want it to be permanent without any event callback
|
||||
*/
|
||||
public void setFireForDuration(int duration, TemporalUnit temporalUnit) {
|
||||
@ -804,8 +790,8 @@ public class LivingEntity extends Entity implements EquipmentHandler {
|
||||
* Note: The strength is reduced based on knockback resistance
|
||||
*
|
||||
* @param strength the strength of the knockback, 0.4 is the vanilla value for a bare hand hit
|
||||
* @param x knockback on x axle, for default knockback use the following formula <pre>sin(attacker.yaw * (pi/180))</pre>
|
||||
* @param z knockback on z axle, for default knockback use the following formula <pre>-cos(attacker.yaw * (pi/180))</pre>
|
||||
* @param x knockback on x axle, for default knockback use the following formula <pre>sin(attacker.yaw * (pi/180))</pre>
|
||||
* @param z knockback on z axle, for default knockback use the following formula <pre>-cos(attacker.yaw * (pi/180))</pre>
|
||||
*/
|
||||
@Override
|
||||
public void takeKnockback(float strength, final double x, final double z) {
|
||||
|
@ -68,6 +68,8 @@ import net.minestom.server.stat.PlayerStatistic;
|
||||
import net.minestom.server.utils.*;
|
||||
import net.minestom.server.utils.chunk.ChunkCallback;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import net.minestom.server.utils.entity.EntityUtils;
|
||||
import net.minestom.server.utils.identity.NamedAndIdentified;
|
||||
import net.minestom.server.utils.instance.InstanceUtils;
|
||||
@ -130,7 +132,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
|
||||
private byte heldSlot;
|
||||
|
||||
private Position respawnPoint;
|
||||
private Pos respawnPoint;
|
||||
|
||||
private int food;
|
||||
private float foodSaturation;
|
||||
@ -179,7 +181,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
|
||||
setBoundingBox(0.6f, 1.8f, 0.6f);
|
||||
|
||||
setRespawnPoint(new Position(0, 0, 0));
|
||||
setRespawnPoint(Pos.ZERO);
|
||||
|
||||
this.settings = new PlayerSettings();
|
||||
this.inventory = new PlayerInventory(this);
|
||||
@ -520,9 +522,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
* @param spawnPosition the new position of the player
|
||||
*/
|
||||
@Override
|
||||
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
|
||||
public void setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) {
|
||||
Check.argCondition(this.instance == instance, "Instance should be different than the current one");
|
||||
|
||||
// true if the chunks need to be sent to the client, can be false if the instances share the same chunks (eg SharedInstance)
|
||||
final boolean needWorldRefresh = !InstanceUtils.areLinked(this.instance, instance) ||
|
||||
!spawnPosition.inSameChunk(this.position);
|
||||
@ -557,7 +558,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
* if the player is not in any instance).
|
||||
*
|
||||
* @param instance the new player instance
|
||||
* @see #setInstance(Instance, Position)
|
||||
* @see #setInstance(Instance, Pos)
|
||||
*/
|
||||
@Override
|
||||
public void setInstance(@NotNull Instance instance) {
|
||||
@ -569,14 +570,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
* <p>
|
||||
* Does add the player to {@code instance}, remove all viewable entities and call {@link PlayerSpawnEvent}.
|
||||
* <p>
|
||||
* UNSAFE: only called with {@link #setInstance(Instance, Position)}.
|
||||
* UNSAFE: only called with {@link #setInstance(Instance, Pos)}.
|
||||
*
|
||||
* @param spawnPosition the position to teleport the player
|
||||
* @param firstSpawn true if this is the player first spawn
|
||||
* @param updateChunks true if chunks should be refreshed, false if the new instance shares the same
|
||||
* chunks
|
||||
*/
|
||||
private void spawnPlayer(@NotNull Instance instance, @NotNull Position spawnPosition,
|
||||
private void spawnPlayer(@NotNull Instance instance, @NotNull Pos spawnPosition,
|
||||
boolean firstSpawn, boolean dimensionChange, boolean updateChunks) {
|
||||
if (!firstSpawn) {
|
||||
// Player instance changed, clear current viewable collections
|
||||
@ -768,7 +769,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
|
||||
@Override
|
||||
public void playSound(@NotNull Sound sound) {
|
||||
this.playSound(sound, this.position.getX(), this.position.getY(), this.position.getZ());
|
||||
this.playSound(sound, this.position.x(), this.position.y(), this.position.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1294,14 +1295,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
facePosition(facePoint, entity.getPosition(), entity, targetPoint);
|
||||
}
|
||||
|
||||
private void facePosition(@NotNull FacePoint facePoint, @NotNull Position targetPosition,
|
||||
private void facePosition(@NotNull FacePoint facePoint, @NotNull Point targetPosition,
|
||||
@Nullable Entity entity, @Nullable FacePoint targetPoint) {
|
||||
FacePlayerPacket facePlayerPacket = new FacePlayerPacket();
|
||||
facePlayerPacket.entityFacePosition = facePoint == FacePoint.EYE ?
|
||||
FacePlayerPacket.FacePosition.EYES : FacePlayerPacket.FacePosition.FEET;
|
||||
facePlayerPacket.targetX = targetPosition.getX();
|
||||
facePlayerPacket.targetY = targetPosition.getY();
|
||||
facePlayerPacket.targetZ = targetPosition.getZ();
|
||||
facePlayerPacket.targetX = targetPosition.x();
|
||||
facePlayerPacket.targetY = targetPosition.y();
|
||||
facePlayerPacket.targetZ = targetPosition.z();
|
||||
if (entity != null) {
|
||||
facePlayerPacket.entityId = entity.getEntityId();
|
||||
facePlayerPacket.entityFacePosition = targetPoint == FacePoint.EYE ?
|
||||
@ -1329,13 +1330,12 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
/**
|
||||
* Used to retrieve the default spawn point.
|
||||
* <p>
|
||||
* Can be altered by the {@link PlayerRespawnEvent#setRespawnPosition(Position)}.
|
||||
* Can be altered by the {@link PlayerRespawnEvent#setRespawnPosition(Pos)}.
|
||||
*
|
||||
* @return a copy of the default respawn point
|
||||
*/
|
||||
@NotNull
|
||||
public Position getRespawnPoint() {
|
||||
return respawnPoint.clone();
|
||||
public @NotNull Pos getRespawnPoint() {
|
||||
return respawnPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1343,7 +1343,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
*
|
||||
* @param respawnPoint the player respawn point
|
||||
*/
|
||||
public void setRespawnPoint(@NotNull Position respawnPoint) {
|
||||
public void setRespawnPoint(@NotNull Pos respawnPoint) {
|
||||
this.respawnPoint = respawnPoint;
|
||||
}
|
||||
|
||||
@ -1365,8 +1365,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
|
||||
{
|
||||
// Send new chunks
|
||||
final BlockPosition pos = position.toBlockPosition();
|
||||
final Chunk chunk = instance.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
|
||||
final Chunk chunk = instance.getChunkAt(position);
|
||||
Check.notNull(chunk, "Tried to interact with an unloaded chunk.");
|
||||
refreshVisibleChunks(chunk);
|
||||
}
|
||||
@ -1903,7 +1902,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
protected void synchronizePosition(boolean includeSelf) {
|
||||
if (includeSelf) {
|
||||
final PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket();
|
||||
positionAndLookPacket.position = position.clone();
|
||||
positionAndLookPacket.position = position;
|
||||
positionAndLookPacket.flags = 0x00;
|
||||
positionAndLookPacket.teleportId = teleportId.incrementAndGet();
|
||||
playerConnection.sendPacket(positionAndLookPacket);
|
||||
@ -2324,7 +2323,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
|
||||
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
||||
entityHeadLookPacket.entityId = getEntityId();
|
||||
entityHeadLookPacket.yaw = position.getYaw();
|
||||
entityHeadLookPacket.yaw = position.yaw();
|
||||
connection.sendPacket(entityHeadLookPacket);
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,10 @@ package net.minestom.server.entity.ai.goal;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.EntityProjectile;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.ai.GoalSelector;
|
||||
import net.minestom.server.entity.pathfinding.Navigator;
|
||||
import net.minestom.server.entity.EntityProjectile;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
@ -175,7 +174,7 @@ public class CombinedAttackGoal extends GoalSelector {
|
||||
if (!Cooldown.hasCooldown(time, this.lastAttack, this.rangedDelay)) {
|
||||
if (this.entityCreature.hasLineOfSight(target)) {
|
||||
// If target is on line of entity sight, ranged attack can be performed
|
||||
Position to = target.getPosition().clone().add(0D, target.getEyeHeight(), 0D);
|
||||
final var to = target.getPosition().add(0D, target.getEyeHeight(), 0D);
|
||||
|
||||
Function<Entity, EntityProjectile> projectileGenerator = this.projectileGenerator;
|
||||
if (projectileGenerator == null) {
|
||||
@ -193,7 +192,7 @@ public class CombinedAttackGoal extends GoalSelector {
|
||||
}
|
||||
}
|
||||
Navigator navigator = this.entityCreature.getNavigator();
|
||||
Position pathPosition = navigator.getPathPosition();
|
||||
final var pathPosition = navigator.getPathPosition();
|
||||
// If we don't want to come close and we're already within desirable range, no movement is needed.
|
||||
if (!comeClose && distanceSquared <= this.desirableRangeSquared) {
|
||||
if (pathPosition != null) {
|
||||
@ -202,8 +201,8 @@ public class CombinedAttackGoal extends GoalSelector {
|
||||
return;
|
||||
}
|
||||
// Otherwise going to the target.
|
||||
Position targetPosition = target.getPosition();
|
||||
if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) {
|
||||
final var targetPosition = target.getPosition();
|
||||
if (pathPosition == null || !pathPosition.samePoint(targetPosition)) {
|
||||
if (this.cooldown.isReady(time)) {
|
||||
this.cooldown.refreshLastUpdate(time);
|
||||
navigator.setPathTo(targetPosition);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -4,8 +4,7 @@ import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.ai.GoalSelector;
|
||||
import net.minestom.server.entity.pathfinding.Navigator;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
@ -15,14 +14,13 @@ public class FollowTargetGoal extends GoalSelector {
|
||||
private final Duration pathDuration;
|
||||
private long lastUpdateTime = 0;
|
||||
private boolean forceEnd = false;
|
||||
private Position lastTargetPos;
|
||||
private Point lastTargetPos;
|
||||
|
||||
/**
|
||||
* Creates a follow target goal object.
|
||||
*
|
||||
* @param entityCreature the entity
|
||||
* @param pathUpdateOption the time between each path update (to check if the target moved)
|
||||
*
|
||||
* @deprecated Replaced by {@link #FollowTargetGoal(EntityCreature, Duration)}
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@ -34,8 +32,8 @@ public class FollowTargetGoal extends GoalSelector {
|
||||
/**
|
||||
* Creates a follow target goal object.
|
||||
*
|
||||
* @param entityCreature the entity
|
||||
* @param pathDuration the time between each path update (to check if the target moved)
|
||||
* @param entityCreature the entity
|
||||
* @param pathDuration the time between each path update (to check if the target moved)
|
||||
*/
|
||||
public FollowTargetGoal(@NotNull EntityCreature entityCreature, @NotNull Duration pathDuration) {
|
||||
super(entityCreature);
|
||||
@ -45,7 +43,7 @@ public class FollowTargetGoal extends GoalSelector {
|
||||
@Override
|
||||
public boolean shouldStart() {
|
||||
return entityCreature.getTarget() != null &&
|
||||
getDistance(entityCreature.getTarget().getPosition(), entityCreature.getPosition()) >= 2;
|
||||
entityCreature.getTarget().getPosition().distance(entityCreature.getPosition()) >= 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -54,19 +52,18 @@ public class FollowTargetGoal extends GoalSelector {
|
||||
forceEnd = false;
|
||||
lastTargetPos = null;
|
||||
final Entity target = entityCreature.getTarget();
|
||||
|
||||
if (target != null) {
|
||||
Navigator navigator = entityCreature.getNavigator();
|
||||
|
||||
lastTargetPos = target.getPosition().clone();
|
||||
if (getDistance(lastTargetPos, entityCreature.getPosition()) < 2) {
|
||||
lastTargetPos = target.getPosition();
|
||||
if (lastTargetPos.distance(entityCreature.getPosition()) < 2) {
|
||||
forceEnd = true;
|
||||
navigator.setPathTo(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (navigator.getPathPosition() == null ||
|
||||
(!navigator.getPathPosition().isSimilar(lastTargetPos))) {
|
||||
(!navigator.getPathPosition().samePoint(lastTargetPos))) {
|
||||
navigator.setPathTo(lastTargetPos);
|
||||
} else {
|
||||
forceEnd = true;
|
||||
@ -83,28 +80,24 @@ public class FollowTargetGoal extends GoalSelector {
|
||||
pathDuration.toMillis() + lastUpdateTime > time) {
|
||||
return;
|
||||
}
|
||||
Position targetPos = entityCreature.getTarget() != null ? entityCreature.getTarget().getPosition() : null;
|
||||
if (targetPos != null && !targetPos.equals(lastTargetPos)) {
|
||||
lastUpdateTime = time;
|
||||
lastTargetPos.copy(lastTargetPos);
|
||||
entityCreature.getNavigator().setPathTo(targetPos);
|
||||
final var targetPos = entityCreature.getTarget() != null ? entityCreature.getTarget().getPosition() : null;
|
||||
if (targetPos != null && !targetPos.samePoint(lastTargetPos)) {
|
||||
this.lastUpdateTime = time;
|
||||
this.lastTargetPos = targetPos;
|
||||
this.entityCreature.getNavigator().setPathTo(targetPos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldEnd() {
|
||||
final Entity target = entityCreature.getTarget();
|
||||
return forceEnd ||
|
||||
entityCreature.getTarget() == null ||
|
||||
getDistance(entityCreature.getTarget().getPosition(), entityCreature.getPosition()) < 2;
|
||||
target == null ||
|
||||
target.getPosition().distance(entityCreature.getPosition()) < 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
entityCreature.getNavigator().setPathTo(null);
|
||||
}
|
||||
|
||||
private double getDistance(@NotNull Position a, @NotNull Position b) {
|
||||
return MathUtils.square(a.getX() - b.getX()) +
|
||||
MathUtils.square(a.getZ() - b.getZ());
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.ai.GoalSelector;
|
||||
import net.minestom.server.entity.ai.TargetSelector;
|
||||
import net.minestom.server.entity.pathfinding.Navigator;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -61,7 +61,7 @@ public class MeleeAttackGoal extends GoalSelector {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
final Position targetPosition = this.cachedTarget.getPosition();
|
||||
final Point targetPosition = this.cachedTarget.getPosition();
|
||||
entityCreature.getNavigator().setPathTo(targetPosition);
|
||||
}
|
||||
|
||||
@ -90,9 +90,9 @@ public class MeleeAttackGoal extends GoalSelector {
|
||||
|
||||
// Move toward the target entity
|
||||
Navigator navigator = entityCreature.getNavigator();
|
||||
final Position pathPosition = navigator.getPathPosition();
|
||||
final Position targetPosition = target.getPosition();
|
||||
if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) {
|
||||
final var pathPosition = navigator.getPathPosition();
|
||||
final var targetPosition = target.getPosition();
|
||||
if (pathPosition == null || !pathPosition.samePoint(targetPosition)) {
|
||||
if (this.cooldown.isReady(time)) {
|
||||
this.cooldown.refreshLastUpdate(time);
|
||||
navigator.setPathTo(targetPosition);
|
||||
|
@ -3,6 +3,7 @@ package net.minestom.server.entity.ai.goal;
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.ai.GoalSelector;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Random;
|
||||
@ -13,20 +14,20 @@ public class RandomLookAroundGoal extends GoalSelector {
|
||||
private static final Random RANDOM = new Random();
|
||||
private final int chancePerTick;
|
||||
private final Supplier<Integer> minimalLookTimeSupplier;
|
||||
private final Function<EntityCreature, Vector> randomDirectionFunction;
|
||||
private Vector lookDirection;
|
||||
private final Function<EntityCreature, Vec> randomDirectionFunction;
|
||||
private Vec lookDirection;
|
||||
private int lookTime = 0;
|
||||
|
||||
public RandomLookAroundGoal(EntityCreature entityCreature, int chancePerTick) {
|
||||
this(entityCreature, chancePerTick,
|
||||
// These two functions act similarily enough to how MC randomly looks around.
|
||||
// These two functions act similarly enough to how MC randomly looks around.
|
||||
|
||||
// Look in one direction for at most 40 ticks and at minimum 20 ticks.
|
||||
() -> 20 + RANDOM.nextInt(20),
|
||||
// Look at a random block
|
||||
(creature) -> {
|
||||
final double n = Math.PI * 2 * RANDOM.nextDouble();
|
||||
return new Vector(
|
||||
return new Vec(
|
||||
(float) Math.cos(n),
|
||||
0,
|
||||
(float) Math.sin(n)
|
||||
@ -44,8 +45,7 @@ public class RandomLookAroundGoal extends GoalSelector {
|
||||
EntityCreature entityCreature,
|
||||
int chancePerTick,
|
||||
@NotNull Supplier<Integer> minimalLookTimeSupplier,
|
||||
@NotNull Function<EntityCreature, Vector> randomDirectionFunction
|
||||
) {
|
||||
@NotNull Function<EntityCreature, Vec> randomDirectionFunction) {
|
||||
super(entityCreature);
|
||||
this.chancePerTick = chancePerTick;
|
||||
this.minimalLookTimeSupplier = minimalLookTimeSupplier;
|
||||
@ -79,6 +79,5 @@ public class RandomLookAroundGoal extends GoalSelector {
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package net.minestom.server.entity.ai.goal;
|
||||
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.ai.GoalSelector;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -14,14 +14,13 @@ public class RandomStrollGoal extends GoalSelector {
|
||||
private static final long DELAY = 2500;
|
||||
|
||||
private final int radius;
|
||||
private final List<Position> closePositions;
|
||||
private final List<Vec> closePositions;
|
||||
|
||||
private long lastStroll;
|
||||
|
||||
public RandomStrollGoal(@NotNull EntityCreature entityCreature, int radius) {
|
||||
super(entityCreature);
|
||||
this.radius = radius;
|
||||
|
||||
this.closePositions = getNearbyBlocks(radius);
|
||||
}
|
||||
|
||||
@ -33,20 +32,17 @@ public class RandomStrollGoal extends GoalSelector {
|
||||
@Override
|
||||
public void start() {
|
||||
Collections.shuffle(closePositions);
|
||||
|
||||
for (Position position : closePositions) {
|
||||
final Position target = position.clone().add(entityCreature.getPosition());
|
||||
for (var position : closePositions) {
|
||||
final var target = entityCreature.getPosition().add(position);
|
||||
final boolean result = entityCreature.getNavigator().setPathTo(target);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(long time) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -64,17 +60,15 @@ public class RandomStrollGoal extends GoalSelector {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<Position> getNearbyBlocks(int radius) {
|
||||
List<Position> blocks = new ArrayList<>();
|
||||
private List<Vec> getNearbyBlocks(int radius) {
|
||||
List<Vec> blocks = new ArrayList<>();
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
for (int y = -radius; y <= radius; y++) {
|
||||
for (int z = -radius; z <= radius; z++) {
|
||||
final Position position = new Position(x, y, z);
|
||||
blocks.add(position);
|
||||
blocks.add(new Vec(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ public class RangedAttackGoal extends GoalSelector {
|
||||
if (distanceSquared <= this.attackRangeSquared) {
|
||||
if (!Cooldown.hasCooldown(time, this.lastShot, this.delay)) {
|
||||
if (this.entityCreature.hasLineOfSight(target)) {
|
||||
Position to = target.getPosition().clone().add(0D, target.getEyeHeight(), 0D);
|
||||
final var to = target.getPosition().add(0D, target.getEyeHeight(), 0D);
|
||||
|
||||
Function<Entity, EntityProjectile> projectileGenerator = this.projectileGenerator;
|
||||
if (projectileGenerator == null) {
|
||||
@ -121,15 +121,15 @@ public class RangedAttackGoal extends GoalSelector {
|
||||
}
|
||||
}
|
||||
Navigator navigator = this.entityCreature.getNavigator();
|
||||
Position pathPosition = navigator.getPathPosition();
|
||||
final var pathPosition = navigator.getPathPosition();
|
||||
if (!comeClose && distanceSquared <= this.desirableRangeSquared) {
|
||||
if (pathPosition != null) {
|
||||
navigator.setPathTo(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Position targetPosition = target.getPosition();
|
||||
if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) {
|
||||
final var targetPosition = target.getPosition();
|
||||
if (pathPosition == null || !pathPosition.samePoint(targetPosition)) {
|
||||
if (this.cooldown.isReady(time)) {
|
||||
this.cooldown.refreshLastUpdate(time);
|
||||
navigator.setPathTo(targetPosition);
|
||||
|
@ -9,6 +9,7 @@ import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.metadata.other.ArmorStandMeta;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -25,7 +26,7 @@ public class Hologram implements Viewable {
|
||||
private final Entity entity;
|
||||
private final float yOffset;
|
||||
|
||||
private Position position;
|
||||
private Pos position;
|
||||
private Component text;
|
||||
|
||||
private boolean removed;
|
||||
@ -36,35 +37,8 @@ public class Hologram implements Viewable {
|
||||
* @param instance The instance where the hologram should be spawned.
|
||||
* @param spawnPosition The spawn position of this hologram.
|
||||
* @param text The text of this hologram.
|
||||
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
|
||||
* @deprecated Use {@link #Hologram(Instance, Position, Component, boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Hologram(Instance instance, Position spawnPosition, JsonMessage text, boolean autoViewable) {
|
||||
this(instance, spawnPosition, text.asComponent(), autoViewable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Hologram} with the given parameters.
|
||||
*
|
||||
* @param instance The instance where the hologram should be spawned.
|
||||
* @param spawnPosition The spawn position of this hologram.
|
||||
* @param text The text of this hologram.
|
||||
* @deprecated Use {@link #Hologram(Instance, Position, Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Hologram(Instance instance, Position spawnPosition, JsonMessage text) {
|
||||
this(instance, spawnPosition, text, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Hologram} with the given parameters.
|
||||
*
|
||||
* @param instance The instance where the hologram should be spawned.
|
||||
* @param spawnPosition The spawn position of this hologram.
|
||||
* @param text The text of this hologram.
|
||||
*/
|
||||
public Hologram(Instance instance, Position spawnPosition, Component text) {
|
||||
public Hologram(Instance instance, Pos spawnPosition, Component text) {
|
||||
this(instance, spawnPosition, text, true);
|
||||
}
|
||||
|
||||
@ -76,7 +50,7 @@ public class Hologram implements Viewable {
|
||||
* @param text The text of this hologram.
|
||||
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
|
||||
*/
|
||||
public Hologram(Instance instance, Position spawnPosition, Component text, boolean autoViewable) {
|
||||
public Hologram(Instance instance, Pos spawnPosition, Component text, boolean autoViewable) {
|
||||
this(instance, spawnPosition, text, autoViewable, false);
|
||||
}
|
||||
|
||||
@ -88,7 +62,7 @@ public class Hologram implements Viewable {
|
||||
* @param text The text of this hologram.
|
||||
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
|
||||
*/
|
||||
public Hologram(Instance instance, Position spawnPosition, Component text, boolean autoViewable, boolean marker) {
|
||||
public Hologram(Instance instance, Pos spawnPosition, Component text, boolean autoViewable, boolean marker) {
|
||||
this.entity = new Entity(EntityType.ARMOR_STAND);
|
||||
|
||||
ArmorStandMeta armorStandMeta = (ArmorStandMeta) entity.getEntityMeta();
|
||||
@ -109,7 +83,7 @@ public class Hologram implements Viewable {
|
||||
|
||||
armorStandMeta.setNotifyAboutChanges(true);
|
||||
|
||||
this.entity.setInstance(instance, spawnPosition.clone().add(0, this.yOffset, 0));
|
||||
this.entity.setInstance(instance, spawnPosition.add(0, this.yOffset, 0));
|
||||
this.entity.setAutoViewable(autoViewable);
|
||||
|
||||
this.position = spawnPosition;
|
||||
@ -121,7 +95,7 @@ public class Hologram implements Viewable {
|
||||
*
|
||||
* @return the hologram's position
|
||||
*/
|
||||
public Position getPosition() {
|
||||
public Pos getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@ -130,11 +104,10 @@ public class Hologram implements Viewable {
|
||||
*
|
||||
* @param position the new hologram's position
|
||||
*/
|
||||
public void setPosition(Position position) {
|
||||
public void setPosition(Pos position) {
|
||||
checkRemoved();
|
||||
position.add(0, this.yOffset, 0);
|
||||
this.position = position;
|
||||
this.entity.teleport(position);
|
||||
this.position = position.add(0, this.yOffset, 0);
|
||||
this.entity.teleport(this.position);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,6 +12,9 @@ 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.coordinate.Point;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
import net.minestom.server.utils.position.PositionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -26,7 +29,7 @@ public class Navigator {
|
||||
private final PFPathingEntity pathingEntity;
|
||||
private HydrazinePathFinder pathFinder;
|
||||
private IPath path;
|
||||
private Position pathPosition;
|
||||
private Point pathPosition;
|
||||
|
||||
private final Entity entity;
|
||||
|
||||
@ -43,17 +46,16 @@ public class Navigator {
|
||||
* @param direction the targeted position
|
||||
* @param speed define how far the entity will move
|
||||
*/
|
||||
public void moveTowards(@NotNull Position direction, double speed) {
|
||||
public void moveTowards(@NotNull Point direction, double speed) {
|
||||
final Pos position = entity.getPosition();
|
||||
|
||||
final Position position = entity.getPosition();
|
||||
final double currentX = position.x();
|
||||
final double currentY = position.y();
|
||||
final double currentZ = position.z();
|
||||
|
||||
final double currentX = position.getX();
|
||||
final double currentY = position.getY();
|
||||
final double currentZ = position.getZ();
|
||||
|
||||
final double targetX = direction.getX();
|
||||
final double targetY = direction.getY();
|
||||
final double targetZ = direction.getZ();
|
||||
final double targetX = direction.x();
|
||||
final double targetY = direction.y();
|
||||
final double targetZ = direction.z();
|
||||
|
||||
final double dx = targetX - currentX;
|
||||
final double dy = targetY - currentY;
|
||||
@ -71,7 +73,7 @@ public class Navigator {
|
||||
final double speedZ = Math.sin(radians) * speed;
|
||||
|
||||
// Update 'position' view
|
||||
PositionUtils.lookAlong(position, dx, direction.getY(), dz);
|
||||
PositionUtils.lookAlong(position, dx, direction.y(), dz);
|
||||
|
||||
Position newPosition = new Position();
|
||||
Vector newVelocityOut = new Vector();
|
||||
@ -87,8 +89,7 @@ public class Navigator {
|
||||
|
||||
public void jump(float height) {
|
||||
// FIXME magic value
|
||||
final Vector velocity = new Vector(0, height * 2.5f, 0);
|
||||
this.entity.setVelocity(velocity);
|
||||
this.entity.setVelocity(new Vec(0, height * 2.5f, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,13 +100,13 @@ public class Navigator {
|
||||
* The position is cloned, if you want the entity to continually follow this position object
|
||||
* you need to call this when you want the path to update.
|
||||
*
|
||||
* @param position the position to find the path to, null to reset the pathfinder
|
||||
* @param point the position to find the path to, null to reset the pathfinder
|
||||
* @param bestEffort whether to use the best-effort algorithm to the destination,
|
||||
* if false then this method is more likely to return immediately
|
||||
* @return true if a path has been found
|
||||
*/
|
||||
public synchronized boolean setPathTo(@Nullable Position position, boolean bestEffort) {
|
||||
if (position != null && pathPosition != null && position.isSimilar(pathPosition)) {
|
||||
public synchronized boolean setPathTo(@Nullable Point point, boolean bestEffort) {
|
||||
if (point != null && pathPosition != null && point.samePoint(pathPosition)) {
|
||||
// Tried to set path to the same target position
|
||||
return false;
|
||||
}
|
||||
@ -118,7 +119,7 @@ public class Navigator {
|
||||
}
|
||||
|
||||
pathFinder.reset();
|
||||
if (position == null) {
|
||||
if (point == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -129,38 +130,36 @@ public class Navigator {
|
||||
|
||||
// Can't path outside of the world border
|
||||
final WorldBorder worldBorder = instance.getWorldBorder();
|
||||
if (!worldBorder.isInside(position)) {
|
||||
if (!worldBorder.isInside(point)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Can't path in an unloaded chunk
|
||||
final Chunk chunk = instance.getChunkAt(position);
|
||||
final Chunk chunk = instance.getChunkAt(point);
|
||||
if (!ChunkUtils.isLoaded(chunk)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Position targetPosition = position.clone();
|
||||
|
||||
final PathOptions pathOptions = new PathOptions()
|
||||
.targetingStrategy(bestEffort ? PathOptions.TargetingStrategy.gravitySnap :
|
||||
PathOptions.TargetingStrategy.none);
|
||||
final IPath path = pathFinder.initiatePathTo(
|
||||
targetPosition.getX(),
|
||||
targetPosition.getY(),
|
||||
targetPosition.getZ(),
|
||||
point.x(),
|
||||
point.y(),
|
||||
point.z(),
|
||||
pathOptions);
|
||||
this.path = path;
|
||||
|
||||
final boolean success = path != null;
|
||||
this.pathPosition = success ? targetPosition : null;
|
||||
this.pathPosition = success ? point : null;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #setPathTo(Position, boolean) with {@code bestEffort} sets to {@code true}.
|
||||
* @see #setPathTo(Point, boolean) with {@code bestEffort} sets to {@code true}.
|
||||
*/
|
||||
public boolean setPathTo(@Nullable Position position) {
|
||||
public boolean setPathTo(@Nullable Point position) {
|
||||
return setPathTo(position, true);
|
||||
}
|
||||
|
||||
@ -174,7 +173,7 @@ public class Navigator {
|
||||
this.path = path;
|
||||
|
||||
if (path != null) {
|
||||
final Position targetPosition = pathingEntity.getTargetPosition();
|
||||
final Point targetPosition = pathingEntity.getTargetPosition();
|
||||
if (targetPosition != null) {
|
||||
moveTowards(targetPosition, speed);
|
||||
}
|
||||
@ -220,8 +219,7 @@ public class Navigator {
|
||||
*
|
||||
* @return the target pathfinder position, null if there is no one
|
||||
*/
|
||||
@Nullable
|
||||
public Position getPathPosition() {
|
||||
public @Nullable Point getPathPosition() {
|
||||
return pathPosition;
|
||||
}
|
||||
|
||||
@ -229,10 +227,10 @@ public class Navigator {
|
||||
* Changes the position this element is trying to reach.
|
||||
*
|
||||
* @param pathPosition the new current path position
|
||||
* @deprecated Please use {@link #setPathTo(Position)}
|
||||
* @deprecated Please use {@link #setPathTo(Point)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setPathPosition(@Nullable Position pathPosition) {
|
||||
public void setPathPosition(@Nullable Point pathPosition) {
|
||||
this.pathPosition = pathPosition;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import net.minestom.server.attribute.Attribute;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.LivingEntity;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PFPathingEntity implements IPathingEntity {
|
||||
@ -16,7 +17,7 @@ public class PFPathingEntity implements IPathingEntity {
|
||||
private final Entity entity;
|
||||
|
||||
private float searchRange;
|
||||
private Position targetPosition;
|
||||
private Point targetPosition;
|
||||
|
||||
// Capacities
|
||||
private boolean fireResistant;
|
||||
@ -36,7 +37,7 @@ public class PFPathingEntity implements IPathingEntity {
|
||||
this.searchRange = getAttributeValue(Attribute.FOLLOW_RANGE);
|
||||
}
|
||||
|
||||
public Position getTargetPosition() {
|
||||
public Point getTargetPosition() {
|
||||
return targetPosition;
|
||||
}
|
||||
|
||||
@ -195,16 +196,16 @@ public class PFPathingEntity implements IPathingEntity {
|
||||
public void moveTo(Vec3d position, Passibility passibility, Gravitation gravitation) {
|
||||
this.targetPosition = new Position(position.x, position.y, position.z);
|
||||
|
||||
final double entityY = entity.getPosition().getY();
|
||||
if (entityY < targetPosition.getY()) {
|
||||
final double entityY = entity.getPosition().y();
|
||||
if (entityY < targetPosition.y()) {
|
||||
this.navigator.jump(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3d coordinates() {
|
||||
final Position position = entity.getPosition();
|
||||
return new Vec3d(position.getX(), position.getY(), position.getZ());
|
||||
final var position = entity.getPosition();
|
||||
return new Vec3d(position.x(), position.y(), position.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,6 +5,7 @@ import net.minestom.server.entity.EntityProjectile;
|
||||
import net.minestom.server.event.trait.CancellableEvent;
|
||||
import net.minestom.server.event.trait.EntityEvent;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@ -14,13 +15,13 @@ public class EntityShootEvent implements EntityEvent, CancellableEvent {
|
||||
|
||||
private final Entity entity;
|
||||
private final Entity projectile;
|
||||
private final Position to;
|
||||
private final Point to;
|
||||
private double power;
|
||||
private double spread;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public EntityShootEvent(@NotNull Entity entity, @NotNull Entity projectile, @NotNull Position to, double power, double spread) {
|
||||
public EntityShootEvent(@NotNull Entity entity, @NotNull Entity projectile, @NotNull Point to, double power, double spread) {
|
||||
this.entity = entity;
|
||||
this.projectile = projectile;
|
||||
this.to = to;
|
||||
@ -42,7 +43,7 @@ public class EntityShootEvent implements EntityEvent, CancellableEvent {
|
||||
*
|
||||
* @return the position projectile was shot to.
|
||||
*/
|
||||
public Position getTo() {
|
||||
public Point getTo() {
|
||||
return this.to;
|
||||
}
|
||||
|
||||
|
@ -3,20 +3,20 @@ package net.minestom.server.event.entity;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.event.trait.CancellableEvent;
|
||||
import net.minestom.server.event.trait.EntityEvent;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a velocity is applied to an entity using {@link Entity#setVelocity(Vector)}.
|
||||
* Called when a velocity is applied to an entity using {@link Entity#setVelocity(Vec)}.
|
||||
*/
|
||||
public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
|
||||
|
||||
private final Entity entity;
|
||||
private Vector velocity;
|
||||
private Vec velocity;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public EntityVelocityEvent(@NotNull Entity entity, @NotNull Vector velocity) {
|
||||
public EntityVelocityEvent(@NotNull Entity entity, @NotNull Vec velocity) {
|
||||
this.entity = entity;
|
||||
this.velocity = velocity;
|
||||
}
|
||||
@ -26,9 +26,8 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
|
||||
*
|
||||
* @return the entity
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public Entity getEntity() {
|
||||
public @NotNull Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
@ -37,8 +36,7 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
|
||||
*
|
||||
* @return the velocity
|
||||
*/
|
||||
@NotNull
|
||||
public Vector getVelocity() {
|
||||
public @NotNull Vec getVelocity() {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
@ -47,7 +45,7 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
|
||||
*
|
||||
* @param velocity the new velocity
|
||||
*/
|
||||
public void setVelocity(@NotNull Vector velocity) {
|
||||
public void setVelocity(@NotNull Vec velocity) {
|
||||
this.velocity = velocity;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ package net.minestom.server.event.player;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.trait.CancellableEvent;
|
||||
import net.minestom.server.event.trait.PlayerEvent;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@ -12,11 +12,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
|
||||
|
||||
private final Player player;
|
||||
private Position newPosition;
|
||||
private Pos newPosition;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerMoveEvent(@NotNull Player player, @NotNull Position newPosition) {
|
||||
public PlayerMoveEvent(@NotNull Player player, @NotNull Pos newPosition) {
|
||||
this.player = player;
|
||||
this.newPosition = newPosition;
|
||||
}
|
||||
@ -26,8 +26,7 @@ public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
|
||||
*
|
||||
* @return the new position
|
||||
*/
|
||||
@NotNull
|
||||
public Position getNewPosition() {
|
||||
public @NotNull Pos getNewPosition() {
|
||||
return newPosition;
|
||||
}
|
||||
|
||||
@ -36,7 +35,7 @@ public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
|
||||
*
|
||||
* @param newPosition the new target position
|
||||
*/
|
||||
public void setNewPosition(@NotNull Position newPosition) {
|
||||
public void setNewPosition(@NotNull Pos newPosition) {
|
||||
this.newPosition = newPosition;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
import net.minestom.server.event.trait.PlayerEvent;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@ -13,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class PlayerRespawnEvent implements PlayerEvent {
|
||||
|
||||
private final Player player;
|
||||
private Position respawnPosition;
|
||||
private Pos respawnPosition;
|
||||
|
||||
public PlayerRespawnEvent(@NotNull Player player) {
|
||||
this.player = player;
|
||||
@ -27,8 +26,7 @@ public class PlayerRespawnEvent implements PlayerEvent {
|
||||
*
|
||||
* @return the respawn position
|
||||
*/
|
||||
@NotNull
|
||||
public Position getRespawnPosition() {
|
||||
public @NotNull Pos getRespawnPosition() {
|
||||
return respawnPosition;
|
||||
}
|
||||
|
||||
@ -37,7 +35,7 @@ public class PlayerRespawnEvent implements PlayerEvent {
|
||||
*
|
||||
* @param respawnPosition the new respawn position
|
||||
*/
|
||||
public void setRespawnPosition(@NotNull Position respawnPosition) {
|
||||
public void setRespawnPosition(@NotNull Pos respawnPosition) {
|
||||
this.respawnPosition = respawnPosition;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.chunk.ChunkCallback;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import net.minestom.server.utils.entity.EntityUtils;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
@ -309,10 +310,10 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
||||
* <p>
|
||||
* Always returning false allow entities to survive in the void.
|
||||
*
|
||||
* @param position the position in the world
|
||||
* @return true iif position is inside the void
|
||||
* @param point the point in the world
|
||||
* @return true if the point is inside the void
|
||||
*/
|
||||
public abstract boolean isInVoid(@NotNull Position position);
|
||||
public abstract boolean isInVoid(@NotNull Point point);
|
||||
|
||||
/**
|
||||
* Gets if the instance has been registered in {@link InstanceManager}.
|
||||
@ -535,12 +536,12 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
||||
/**
|
||||
* Loads the chunk at the given {@link Position} with a callback.
|
||||
*
|
||||
* @param position the chunk position
|
||||
* @param point the chunk position
|
||||
* @param callback the optional callback to run when the chunk is loaded
|
||||
*/
|
||||
public void loadChunk(@NotNull Position position, @Nullable ChunkCallback callback) {
|
||||
final int chunkX = ChunkUtils.getChunkCoordinate(position.getX());
|
||||
final int chunkZ = ChunkUtils.getChunkCoordinate(position.getZ());
|
||||
public void loadChunk(@NotNull Point point, @Nullable ChunkCallback callback) {
|
||||
final int chunkX = ChunkUtils.getChunkCoordinate(point.x());
|
||||
final int chunkZ = ChunkUtils.getChunkCoordinate(point.z());
|
||||
loadChunk(chunkX, chunkZ, callback);
|
||||
}
|
||||
|
||||
@ -548,12 +549,12 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
||||
* Loads a {@link Chunk} (if {@link #hasEnabledAutoChunkLoad()} returns true)
|
||||
* at the given {@link Position} with a callback.
|
||||
*
|
||||
* @param position the chunk position
|
||||
* @param point the chunk position
|
||||
* @param callback the optional callback executed when the chunk is loaded (or with a null chunk if not)
|
||||
*/
|
||||
public void loadOptionalChunk(@NotNull Position position, @Nullable ChunkCallback callback) {
|
||||
final int chunkX = ChunkUtils.getChunkCoordinate(position.getX());
|
||||
final int chunkZ = ChunkUtils.getChunkCoordinate(position.getZ());
|
||||
public void loadOptionalChunk(@NotNull Point point, @Nullable ChunkCallback callback) {
|
||||
final int chunkX = ChunkUtils.getChunkCoordinate(point.x());
|
||||
final int chunkZ = ChunkUtils.getChunkCoordinate(point.z());
|
||||
loadOptionalChunk(chunkX, chunkZ, callback);
|
||||
}
|
||||
|
||||
@ -703,7 +704,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
|
||||
}
|
||||
AddEntityToInstanceEvent event = new AddEntityToInstanceEvent(this, entity);
|
||||
EventDispatcher.callCancellable(event, () -> {
|
||||
final Position entityPosition = entity.getPosition();
|
||||
final Pos entityPosition = entity.getPosition();
|
||||
final boolean isPlayer = entity instanceof Player;
|
||||
|
||||
if (isPlayer) {
|
||||
|
@ -19,7 +19,6 @@ import net.minestom.server.network.packet.server.play.UnloadChunkPacket;
|
||||
import net.minestom.server.storage.StorageLocation;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.callback.OptionalCallback;
|
||||
import net.minestom.server.utils.chunk.ChunkCallback;
|
||||
import net.minestom.server.utils.chunk.ChunkSupplier;
|
||||
@ -385,9 +384,9 @@ public class InstanceContainer extends Instance {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInVoid(@NotNull Position position) {
|
||||
public boolean isInVoid(@NotNull Point point) {
|
||||
// TODO: customizable
|
||||
return position.getY() < -64;
|
||||
return point.y() < -64;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,6 @@ import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockFace;
|
||||
import net.minestom.server.storage.StorageLocation;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.chunk.ChunkCallback;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -119,8 +118,8 @@ public class SharedInstance extends Instance {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInVoid(@NotNull Position position) {
|
||||
return instanceContainer.isInVoid(position);
|
||||
public boolean isInVoid(@NotNull Point point) {
|
||||
return instanceContainer.isInVoid(point);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,7 @@ import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.play.*;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@ -159,14 +159,13 @@ public class WorldBorder {
|
||||
/**
|
||||
* Used to check at which axis does the position collides with the world border.
|
||||
*
|
||||
* @param position the position to check
|
||||
* @param point the point to check
|
||||
* @return the axis where the position collides with the world border
|
||||
*/
|
||||
@NotNull
|
||||
public CollisionAxis getCollisionAxis(@NotNull Position position) {
|
||||
public @NotNull CollisionAxis getCollisionAxis(@NotNull Point point) {
|
||||
final double radius = getDiameter() / 2d;
|
||||
final boolean checkX = position.getX() <= getCenterX() + radius && position.getX() >= getCenterX() - radius;
|
||||
final boolean checkZ = position.getZ() <= getCenterZ() + radius && position.getZ() >= getCenterZ() - radius;
|
||||
final boolean checkX = point.x() <= getCenterX() + radius && point.x() >= getCenterX() - radius;
|
||||
final boolean checkZ = point.z() <= getCenterZ() + radius && point.z() >= getCenterZ() - radius;
|
||||
if (!checkX && !checkZ) {
|
||||
return CollisionAxis.BOTH;
|
||||
} else if (!checkX) {
|
||||
@ -180,11 +179,11 @@ public class WorldBorder {
|
||||
/**
|
||||
* Used to know if a position is located inside the world border or not.
|
||||
*
|
||||
* @param position the position to check
|
||||
* @param point the point to check
|
||||
* @return true if {@code position} is inside the world border, false otherwise
|
||||
*/
|
||||
public boolean isInside(@NotNull Position position) {
|
||||
return getCollisionAxis(position) == CollisionAxis.NONE;
|
||||
public boolean isInside(@NotNull Point point) {
|
||||
return getCollisionAxis(point) == CollisionAxis.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,7 +155,7 @@ public class StairsPlacementRule extends BlockPlacementRule {
|
||||
|
||||
@NotNull
|
||||
private Facing getFacing(@NotNull Player player) {
|
||||
float degrees = (player.getPosition().getYaw() - 90) % 360;
|
||||
float degrees = (player.getPosition().yaw() - 90) % 360;
|
||||
if (degrees < 0) {
|
||||
degrees += 360;
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.StackingRule;
|
||||
import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket;
|
||||
import net.minestom.server.network.packet.server.play.AcknowledgePlayerDiggingPacket;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -150,11 +149,10 @@ public class PlayerDiggingListener {
|
||||
|
||||
if (!result) {
|
||||
if (block.isSolid()) {
|
||||
final BlockPosition playerBlockPosition = player.getPosition().toBlockPosition();
|
||||
|
||||
final var playerPosition = player.getPosition();
|
||||
// Teleport the player back if he broke a solid block just below him
|
||||
if (playerBlockPosition.subtract(0, 1, 0).equals(blockPosition))
|
||||
player.teleport(player.getPosition());
|
||||
if (playerPosition.sub(0, 1, 0).samePoint(blockPosition))
|
||||
player.teleport(playerPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import net.minestom.server.event.EventDispatcher;
|
||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.network.packet.client.play.*;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PlayerPositionListener {
|
||||
@ -16,10 +16,10 @@ public class PlayerPositionListener {
|
||||
}
|
||||
|
||||
public static void playerLookListener(ClientPlayerRotationPacket packet, Player player) {
|
||||
final Position playerPosition = player.getPosition();
|
||||
final double x = playerPosition.getX();
|
||||
final double y = playerPosition.getY();
|
||||
final double z = playerPosition.getZ();
|
||||
final var playerPosition = player.getPosition();
|
||||
final double x = playerPosition.x();
|
||||
final double y = playerPosition.y();
|
||||
final double z = playerPosition.z();
|
||||
final float yaw = packet.yaw;
|
||||
final float pitch = packet.pitch;
|
||||
final boolean onGround = packet.onGround;
|
||||
@ -27,9 +27,9 @@ public class PlayerPositionListener {
|
||||
}
|
||||
|
||||
public static void playerPositionListener(ClientPlayerPositionPacket packet, Player player) {
|
||||
final Position playerPosition = player.getPosition();
|
||||
final float yaw = playerPosition.getYaw();
|
||||
final float pitch = playerPosition.getPitch();
|
||||
final var playerPosition = player.getPosition();
|
||||
final float yaw = playerPosition.yaw();
|
||||
final float pitch = playerPosition.pitch();
|
||||
final boolean onGround = packet.onGround;
|
||||
processMovement(player,
|
||||
packet.x, packet.y, packet.z,
|
||||
@ -53,46 +53,35 @@ public class PlayerPositionListener {
|
||||
private static void processMovement(@NotNull Player player, double x, double y, double z,
|
||||
float yaw, float pitch, boolean onGround) {
|
||||
final Instance instance = player.getInstance();
|
||||
|
||||
// Prevent moving before the player spawned, probably a modified client (or high latency?)
|
||||
if (instance == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent the player from moving during a teleport
|
||||
if (player.getLastSentTeleportId() != player.getLastReceivedTeleportId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to move in an unloaded chunk, prevent it
|
||||
if (!ChunkUtils.isLoaded(instance, x, z)) {
|
||||
player.teleport(player.getPosition());
|
||||
return;
|
||||
}
|
||||
|
||||
final Position currentPosition = player.getPosition().clone();
|
||||
Position newPosition = new Position(x, y, z, yaw, pitch);
|
||||
final Position cachedPosition = newPosition.clone();
|
||||
final var currentPosition = player.getPosition();
|
||||
final var newPosition = new Pos(x, y, z, yaw, pitch);
|
||||
|
||||
PlayerMoveEvent playerMoveEvent = new PlayerMoveEvent(player, newPosition);
|
||||
EventDispatcher.call(playerMoveEvent);
|
||||
|
||||
// True if the event call changed the player position (possibly a teleport)
|
||||
final boolean positionChanged = !currentPosition.equals(player.getPosition());
|
||||
|
||||
if (!playerMoveEvent.isCancelled() && !positionChanged) {
|
||||
// Move the player
|
||||
newPosition = playerMoveEvent.getNewPosition();
|
||||
if (!newPosition.equals(cachedPosition)) {
|
||||
// New position from the event changed, teleport the player
|
||||
player.teleport(newPosition);
|
||||
}
|
||||
// Change the internal data
|
||||
player.refreshPosition(newPosition);
|
||||
player.refreshPosition(playerMoveEvent.getNewPosition());
|
||||
player.refreshOnGround(onGround);
|
||||
} else {
|
||||
// Cancelled, teleport to previous position
|
||||
player.teleport(player.getPosition());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import net.minestom.server.entity.metadata.other.BoatMeta;
|
||||
import net.minestom.server.network.packet.client.play.ClientSteerBoatPacket;
|
||||
import net.minestom.server.network.packet.client.play.ClientSteerVehiclePacket;
|
||||
import net.minestom.server.network.packet.client.play.ClientVehicleMovePacket;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
|
||||
public class PlayerVehicleListener {
|
||||
|
||||
@ -19,11 +19,10 @@ public class PlayerVehicleListener {
|
||||
|
||||
public static void vehicleMoveListener(ClientVehicleMovePacket packet, Player player) {
|
||||
final Entity vehicle = player.getVehicle();
|
||||
|
||||
if (vehicle == null)
|
||||
return;
|
||||
|
||||
final Position newPosition = new Position((float) packet.x, (float) packet.y, (float) packet.z, packet.yaw, packet.pitch);
|
||||
final var newPosition = new Pos(packet.x, packet.y, packet.z, packet.yaw, packet.pitch);
|
||||
vehicle.refreshPosition(newPosition);
|
||||
|
||||
// This packet causes weird screen distortion
|
||||
@ -39,7 +38,6 @@ public class PlayerVehicleListener {
|
||||
|
||||
public static void boatSteerListener(ClientSteerBoatPacket packet, Player player) {
|
||||
final Entity vehicle = player.getVehicle();
|
||||
|
||||
if (!(vehicle.getEntityMeta() instanceof BoatMeta))
|
||||
return;
|
||||
|
||||
@ -47,5 +45,4 @@ public class PlayerVehicleListener {
|
||||
boat.setLeftPaddleTurning(packet.leftPaddleTurning);
|
||||
boat.setRightPaddleTurning(packet.rightPaddleTurning);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class EntityPositionAndRotationPacket implements ServerPacket {
|
||||
@ -14,7 +14,8 @@ public class EntityPositionAndRotationPacket implements ServerPacket {
|
||||
public float yaw, pitch;
|
||||
public boolean onGround;
|
||||
|
||||
public EntityPositionAndRotationPacket() {}
|
||||
public EntityPositionAndRotationPacket() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
@ -44,15 +45,15 @@ public class EntityPositionAndRotationPacket implements ServerPacket {
|
||||
}
|
||||
|
||||
public static EntityPositionAndRotationPacket getPacket(int entityId,
|
||||
@NotNull Position newPosition, @NotNull Position oldPosition,
|
||||
@NotNull Pos newPosition, @NotNull Pos oldPosition,
|
||||
boolean onGround) {
|
||||
EntityPositionAndRotationPacket entityPositionAndRotationPacket = new EntityPositionAndRotationPacket();
|
||||
entityPositionAndRotationPacket.entityId = entityId;
|
||||
entityPositionAndRotationPacket.deltaX = (short) ((newPosition.getX() * 32 - oldPosition.getX() * 32) * 128);
|
||||
entityPositionAndRotationPacket.deltaY = (short) ((newPosition.getY() * 32 - oldPosition.getY() * 32) * 128);
|
||||
entityPositionAndRotationPacket.deltaZ = (short) ((newPosition.getZ() * 32 - oldPosition.getZ() * 32) * 128);
|
||||
entityPositionAndRotationPacket.yaw = newPosition.getYaw();
|
||||
entityPositionAndRotationPacket.pitch = newPosition.getPitch();
|
||||
entityPositionAndRotationPacket.deltaX = (short) ((newPosition.x() * 32 - oldPosition.x() * 32) * 128);
|
||||
entityPositionAndRotationPacket.deltaY = (short) ((newPosition.y() * 32 - oldPosition.y() * 32) * 128);
|
||||
entityPositionAndRotationPacket.deltaZ = (short) ((newPosition.z() * 32 - oldPosition.z() * 32) * 128);
|
||||
entityPositionAndRotationPacket.yaw = newPosition.yaw();
|
||||
entityPositionAndRotationPacket.pitch = newPosition.pitch();
|
||||
entityPositionAndRotationPacket.onGround = onGround;
|
||||
|
||||
return entityPositionAndRotationPacket;
|
||||
|
@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class EntityPositionPacket implements ServerPacket {
|
||||
@ -13,7 +13,8 @@ public class EntityPositionPacket implements ServerPacket {
|
||||
public short deltaX, deltaY, deltaZ;
|
||||
public boolean onGround;
|
||||
|
||||
public EntityPositionPacket() {}
|
||||
public EntityPositionPacket() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
@ -40,13 +41,13 @@ public class EntityPositionPacket implements ServerPacket {
|
||||
|
||||
@NotNull
|
||||
public static EntityPositionPacket getPacket(int entityId,
|
||||
@NotNull Position newPosition, @NotNull Position oldPosition,
|
||||
@NotNull Pos newPosition, @NotNull Pos oldPosition,
|
||||
boolean onGround) {
|
||||
EntityPositionPacket entityPositionPacket = new EntityPositionPacket();
|
||||
entityPositionPacket.entityId = entityId;
|
||||
entityPositionPacket.deltaX = (short) ((newPosition.getX() * 32 - oldPosition.getX() * 32) * 128);
|
||||
entityPositionPacket.deltaY = (short) ((newPosition.getY() * 32 - oldPosition.getY() * 32) * 128);
|
||||
entityPositionPacket.deltaZ = (short) ((newPosition.getZ() * 32 - oldPosition.getZ() * 32) * 128);
|
||||
entityPositionPacket.deltaX = (short) ((newPosition.x() * 32 - oldPosition.x() * 32) * 128);
|
||||
entityPositionPacket.deltaY = (short) ((newPosition.y() * 32 - oldPosition.y() * 32) * 128);
|
||||
entityPositionPacket.deltaZ = (short) ((newPosition.z() * 32 - oldPosition.z() * 32) * 128);
|
||||
entityPositionPacket.onGround = onGround;
|
||||
|
||||
return entityPositionPacket;
|
||||
|
@ -2,42 +2,42 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class EntityTeleportPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public Position position;
|
||||
public Pos position;
|
||||
public boolean onGround;
|
||||
|
||||
public EntityTeleportPacket() {
|
||||
position = new Position();
|
||||
position = Pos.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeVarInt(entityId);
|
||||
writer.writeDouble(position.getX());
|
||||
writer.writeDouble(position.getY());
|
||||
writer.writeDouble(position.getZ());
|
||||
writer.writeByte((byte) (position.getYaw() * 256f / 360f));
|
||||
writer.writeByte((byte) (position.getPitch() * 256f / 360f));
|
||||
writer.writeDouble(position.x());
|
||||
writer.writeDouble(position.y());
|
||||
writer.writeDouble(position.z());
|
||||
writer.writeByte((byte) (position.yaw() * 256f / 360f));
|
||||
writer.writeByte((byte) (position.pitch() * 256f / 360f));
|
||||
writer.writeBoolean(onGround);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(@NotNull BinaryReader reader) {
|
||||
entityId = reader.readVarInt();
|
||||
position = new Position(
|
||||
position = new Pos(
|
||||
reader.readDouble(),
|
||||
reader.readDouble(),
|
||||
reader.readDouble(),
|
||||
reader.readByte() * 360f / 256f,
|
||||
reader.readByte() * 360f / 256f
|
||||
);
|
||||
);
|
||||
onGround = reader.readBoolean();
|
||||
}
|
||||
|
||||
|
@ -2,30 +2,30 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PlayerPositionAndLookPacket implements ServerPacket {
|
||||
|
||||
public Position position;
|
||||
public Pos position;
|
||||
public byte flags;
|
||||
public int teleportId;
|
||||
public boolean dismountVehicle;
|
||||
|
||||
public PlayerPositionAndLookPacket() {
|
||||
position = new Position();
|
||||
position = Pos.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeDouble(position.getX());
|
||||
writer.writeDouble(position.getY());
|
||||
writer.writeDouble(position.getZ());
|
||||
writer.writeDouble(position.x());
|
||||
writer.writeDouble(position.y());
|
||||
writer.writeDouble(position.z());
|
||||
|
||||
writer.writeFloat(position.getYaw());
|
||||
writer.writeFloat(position.getPitch());
|
||||
writer.writeFloat(position.yaw());
|
||||
writer.writeFloat(position.pitch());
|
||||
|
||||
writer.writeByte(flags);
|
||||
writer.writeVarInt(teleportId);
|
||||
@ -34,7 +34,7 @@ public class PlayerPositionAndLookPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public void read(@NotNull BinaryReader reader) {
|
||||
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble(), reader.readFloat(), reader.readFloat());
|
||||
position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(), reader.readFloat(), reader.readFloat());
|
||||
|
||||
flags = reader.readByte();
|
||||
teleportId = reader.readVarInt();
|
||||
|
@ -5,9 +5,9 @@ import net.minestom.server.adventure.AdventurePacketConvertor;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.sound.SoundEvent;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SoundEffectPacket implements ServerPacket {
|
||||
@ -23,18 +23,19 @@ public class SoundEffectPacket implements ServerPacket {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SoundEffectPacket create(Source category, SoundEvent sound, Position position, float volume, float pitch) {
|
||||
public static SoundEffectPacket create(Source category, SoundEvent sound, Pos position, float volume, float pitch) {
|
||||
SoundEffectPacket packet = new SoundEffectPacket();
|
||||
packet.soundId = sound.getId();
|
||||
packet.soundSource = category;
|
||||
// *8 converts to fixed-point representation with 3 bits for fractional part
|
||||
packet.x = (int) position.getX();
|
||||
packet.y = (int) position.getY();
|
||||
packet.z = (int) position.getZ();
|
||||
packet.x = (int) position.x();
|
||||
packet.y = (int) position.y();
|
||||
packet.z = (int) position.z();
|
||||
packet.volume = volume;
|
||||
packet.pitch = pitch;
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeVarInt(soundId);
|
||||
@ -50,9 +51,9 @@ public class SoundEffectPacket implements ServerPacket {
|
||||
public void read(@NotNull BinaryReader reader) {
|
||||
soundId = reader.readVarInt();
|
||||
soundSource = Source.values()[reader.readVarInt()];
|
||||
x = reader.readInt()/8;
|
||||
y = reader.readInt()/8;
|
||||
z = reader.readInt()/8;
|
||||
x = reader.readInt() / 8;
|
||||
y = reader.readInt() / 8;
|
||||
z = reader.readInt() / 8;
|
||||
volume = reader.readFloat();
|
||||
pitch = reader.readFloat();
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
@ -14,13 +14,13 @@ public class SpawnEntityPacket implements ServerPacket {
|
||||
public int entityId;
|
||||
public UUID uuid;
|
||||
public int type;
|
||||
public Position position;
|
||||
public Pos position;
|
||||
public int data;
|
||||
public short velocityX, velocityY, velocityZ;
|
||||
|
||||
public SpawnEntityPacket() {
|
||||
uuid = new UUID(0, 0);
|
||||
position = new Position();
|
||||
position = Pos.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -29,12 +29,12 @@ public class SpawnEntityPacket implements ServerPacket {
|
||||
writer.writeUuid(uuid);
|
||||
writer.writeVarInt(type);
|
||||
|
||||
writer.writeDouble(position.getX());
|
||||
writer.writeDouble(position.getY());
|
||||
writer.writeDouble(position.getZ());
|
||||
writer.writeDouble(position.x());
|
||||
writer.writeDouble(position.y());
|
||||
writer.writeDouble(position.z());
|
||||
|
||||
writer.writeByte((byte) (position.getYaw() * 256 / 360));
|
||||
writer.writeByte((byte) (position.getPitch() * 256 / 360));
|
||||
writer.writeByte((byte) (position.yaw() * 256 / 360));
|
||||
writer.writeByte((byte) (position.pitch() * 256 / 360));
|
||||
|
||||
writer.writeInt(data);
|
||||
|
||||
@ -49,10 +49,9 @@ public class SpawnEntityPacket implements ServerPacket {
|
||||
uuid = reader.readUuid();
|
||||
type = reader.readVarInt();
|
||||
|
||||
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble());
|
||||
|
||||
position.setYaw(reader.readByte() * 360f / 256f);
|
||||
position.setPitch(reader.readByte() * 360f / 256f);
|
||||
position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(),
|
||||
reader.readByte() * 360f / 256f,
|
||||
reader.readByte() * 360f / 256f);
|
||||
|
||||
data = reader.readInt();
|
||||
|
||||
|
@ -2,34 +2,34 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SpawnExperienceOrbPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public Position position;
|
||||
public Pos position;
|
||||
public short expCount;
|
||||
|
||||
public SpawnExperienceOrbPacket() {
|
||||
position = new Position();
|
||||
position = Pos.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeVarInt(entityId);
|
||||
writer.writeDouble(position.getX());
|
||||
writer.writeDouble(position.getY());
|
||||
writer.writeDouble(position.getZ());
|
||||
writer.writeDouble(position.x());
|
||||
writer.writeDouble(position.y());
|
||||
writer.writeDouble(position.z());
|
||||
writer.writeShort(expCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(@NotNull BinaryReader reader) {
|
||||
entityId = reader.readVarInt();
|
||||
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble());
|
||||
position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble());
|
||||
expCount = reader.readShort();
|
||||
}
|
||||
|
||||
|
@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
@ -14,13 +14,13 @@ public class SpawnLivingEntityPacket implements ServerPacket {
|
||||
public int entityId;
|
||||
public UUID entityUuid;
|
||||
public int entityType;
|
||||
public Position position;
|
||||
public Pos position;
|
||||
public float headPitch;
|
||||
public short velocityX, velocityY, velocityZ;
|
||||
|
||||
public SpawnLivingEntityPacket() {
|
||||
entityUuid = new UUID(0, 0);
|
||||
position = new Position();
|
||||
position = Pos.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -29,12 +29,12 @@ public class SpawnLivingEntityPacket implements ServerPacket {
|
||||
writer.writeUuid(entityUuid);
|
||||
writer.writeVarInt(entityType);
|
||||
|
||||
writer.writeDouble(position.getX());
|
||||
writer.writeDouble(position.getY());
|
||||
writer.writeDouble(position.getZ());
|
||||
writer.writeDouble(position.x());
|
||||
writer.writeDouble(position.y());
|
||||
writer.writeDouble(position.z());
|
||||
|
||||
writer.writeByte((byte) (position.getYaw() * 256 / 360));
|
||||
writer.writeByte((byte) (position.getPitch() * 256 / 360));
|
||||
writer.writeByte((byte) (position.yaw() * 256 / 360));
|
||||
writer.writeByte((byte) (position.pitch() * 256 / 360));
|
||||
writer.writeByte((byte) (headPitch * 256 / 360));
|
||||
|
||||
writer.writeShort(velocityX);
|
||||
@ -48,10 +48,9 @@ public class SpawnLivingEntityPacket implements ServerPacket {
|
||||
entityUuid = reader.readUuid();
|
||||
entityType = reader.readVarInt();
|
||||
|
||||
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble());
|
||||
|
||||
position.setYaw(reader.readByte() * 360f / 256f);
|
||||
position.setPitch(reader.readByte() * 360f / 256f);
|
||||
position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(),
|
||||
reader.readByte() * 360f / 256f,
|
||||
reader.readByte() * 360f / 256f);
|
||||
headPitch = reader.readByte() * 360f / 256f;
|
||||
|
||||
velocityX = reader.readShort();
|
||||
|
@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
@ -13,31 +13,31 @@ public class SpawnPlayerPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public UUID playerUuid;
|
||||
public Position position;
|
||||
public Pos position;
|
||||
|
||||
public SpawnPlayerPacket() {
|
||||
playerUuid = new UUID(0,0);
|
||||
position = new Position();
|
||||
playerUuid = new UUID(0, 0);
|
||||
position = Pos.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeVarInt(entityId);
|
||||
writer.writeUuid(playerUuid);
|
||||
writer.writeDouble(position.getX());
|
||||
writer.writeDouble(position.getY());
|
||||
writer.writeDouble(position.getZ());
|
||||
writer.writeByte((byte) (position.getYaw() * 256f / 360f));
|
||||
writer.writeByte((byte) (position.getPitch() * 256f / 360f));
|
||||
writer.writeDouble(position.x());
|
||||
writer.writeDouble(position.y());
|
||||
writer.writeDouble(position.z());
|
||||
writer.writeByte((byte) (position.yaw() * 256f / 360f));
|
||||
writer.writeByte((byte) (position.pitch() * 256f / 360f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(@NotNull BinaryReader reader) {
|
||||
entityId = reader.readVarInt();
|
||||
playerUuid = reader.readUuid();
|
||||
position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble());
|
||||
position.setYaw((reader.readByte() * 360f) / 256f);
|
||||
position.setPitch((reader.readByte() * 360f) / 256f);
|
||||
this.entityId = reader.readVarInt();
|
||||
this.playerUuid = reader.readUuid();
|
||||
this.position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(),
|
||||
(reader.readByte() * 360f) / 256f,
|
||||
(reader.readByte() * 360f) / 256f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,6 +5,7 @@ import net.minestom.server.instance.block.BlockFace;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
@ -228,7 +229,7 @@ public class BlockIterator implements Iterator<BlockPosition> {
|
||||
* trace. Setting this value above 140 may lead to problems with
|
||||
* unloaded chunks. A value of 0 indicates no limit
|
||||
*/
|
||||
public BlockIterator(@NotNull Position pos, double yOffset, int maxDistance) {
|
||||
public BlockIterator(@NotNull Pos pos, double yOffset, int maxDistance) {
|
||||
this(pos.toVector(), pos.getDirection(), yOffset, maxDistance);
|
||||
}
|
||||
|
||||
@ -242,7 +243,7 @@ public class BlockIterator implements Iterator<BlockPosition> {
|
||||
* by this value
|
||||
*/
|
||||
|
||||
public BlockIterator(@NotNull Position pos, double yOffset) {
|
||||
public BlockIterator(@NotNull Pos pos, double yOffset) {
|
||||
this(pos.toVector(), pos.getDirection(), yOffset, 0);
|
||||
}
|
||||
|
||||
@ -254,7 +255,7 @@ public class BlockIterator implements Iterator<BlockPosition> {
|
||||
* @param pos The position for the start of the ray trace
|
||||
*/
|
||||
|
||||
public BlockIterator(@NotNull Position pos) {
|
||||
public BlockIterator(@NotNull Pos pos) {
|
||||
this(pos, 0f);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.callback.OptionalCallback;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -103,8 +104,8 @@ public final class ChunkUtils {
|
||||
return originChunk;
|
||||
}
|
||||
|
||||
public static Chunk retrieve(Instance instance, Chunk originChunk, Position position) {
|
||||
return retrieve(instance, originChunk, position.getX(), position.getZ());
|
||||
public static Chunk retrieve(Instance instance, Chunk originChunk, Point position) {
|
||||
return retrieve(instance, originChunk, position.x(), position.z());
|
||||
}
|
||||
|
||||
public static Chunk retrieve(Instance instance, Chunk originChunk, BlockPosition blockPosition) {
|
||||
@ -170,11 +171,11 @@ public final class ChunkUtils {
|
||||
/**
|
||||
* Gets the chunks in range of a position.
|
||||
*
|
||||
* @param position the initial position
|
||||
* @param point the initial point
|
||||
* @param range how far should it retrieves chunk
|
||||
* @return an array containing chunks index
|
||||
*/
|
||||
public static long @NotNull [] getChunksInRange(@NotNull Position position, int range) {
|
||||
public static long @NotNull [] getChunksInRange(@NotNull Point point, int range) {
|
||||
long[] visibleChunks = new long[MathUtils.square(range * 2 + 1)];
|
||||
int xDistance = 0;
|
||||
int xDirection = 1;
|
||||
@ -184,8 +185,8 @@ public final class ChunkUtils {
|
||||
int corner = 0;
|
||||
|
||||
for (int i = 0; i < visibleChunks.length; i++) {
|
||||
final int chunkX = getChunkCoordinate(xDistance * Chunk.CHUNK_SIZE_X + position.getX());
|
||||
final int chunkZ = getChunkCoordinate(zDistance * Chunk.CHUNK_SIZE_Z + position.getZ());
|
||||
final int chunkX = getChunkCoordinate(xDistance * Chunk.CHUNK_SIZE_X + point.x());
|
||||
final int chunkZ = getChunkCoordinate(zDistance * Chunk.CHUNK_SIZE_Z + point.z());
|
||||
visibleChunks[i] = getChunkIndex(chunkX, chunkZ);
|
||||
|
||||
if (corner % 2 == 0) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.minestom.server.utils.coordinate;
|
||||
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -138,4 +139,27 @@ public interface Point {
|
||||
MathUtils.square(y() - point.y()) +
|
||||
MathUtils.square(z() - point.z());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks it two points have similar (x/y/z).
|
||||
*
|
||||
* @param point the point to compare
|
||||
* @return true if the two positions are similar
|
||||
*/
|
||||
default boolean samePoint(@NotNull Point point) {
|
||||
return Double.compare(point.x(), x()) == 0 &&
|
||||
Double.compare(point.y(), y()) == 0 &&
|
||||
Double.compare(point.z(), z()) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if two points are in the same chunk.
|
||||
*
|
||||
* @param point the point to compare two
|
||||
* @return true if 'this' is in the same chunk as {@code position}
|
||||
*/
|
||||
default boolean inSameChunk(@NotNull Point point) {
|
||||
return ChunkUtils.getChunkCoordinate(x()) == ChunkUtils.getChunkCoordinate(point.x()) &&
|
||||
ChunkUtils.getChunkCoordinate(z()) == ChunkUtils.getChunkCoordinate(point.z());
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package net.minestom.server.utils.coordinate;
|
||||
|
||||
import net.minestom.server.utils.Position;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.DoubleUnaryOperator;
|
||||
|
||||
/**
|
||||
@ -11,6 +13,8 @@ import java.util.function.DoubleUnaryOperator;
|
||||
* To become record and primitive.
|
||||
*/
|
||||
public final class Pos implements Point {
|
||||
public static final Pos ZERO = new Pos(0, 0, 0);
|
||||
|
||||
private final double x, y, z;
|
||||
private final float yaw, pitch;
|
||||
|
||||
@ -34,6 +38,10 @@ public final class Pos implements Point {
|
||||
this(point, 0, 0);
|
||||
}
|
||||
|
||||
public static @NotNull Pos fromPosition(@NotNull Position position) {
|
||||
return new Pos(position.getX(), position.getY(), position.getZ(), position.getYaw(), position.getPitch());
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
public @NotNull Pos withCoord(double x, double y, double z) {
|
||||
return new Pos(x, y, z, yaw, pitch);
|
||||
@ -69,6 +77,33 @@ public final class Pos implements Point {
|
||||
return new Pos(x, y, z, yaw, (float) operator.applyAsDouble(pitch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if two positions have a similar view (yaw/pitch).
|
||||
*
|
||||
* @param position the position to compare
|
||||
* @return true if the two positions have the same view
|
||||
*/
|
||||
public boolean sameView(@NotNull Pos position) {
|
||||
return Float.compare(position.yaw, yaw) == 0 &&
|
||||
Float.compare(position.pitch, pitch) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a unit-vector pointing in the direction that this Location is
|
||||
* facing.
|
||||
*
|
||||
* @return a vector pointing the direction of this location's {@link
|
||||
* #pitch() pitch} and {@link #yaw() yaw}
|
||||
*/
|
||||
public @NotNull Vec direction() {
|
||||
final float rotX = yaw;
|
||||
final float rotY = pitch;
|
||||
final double xz = Math.cos(Math.toRadians(rotY));
|
||||
return new Vec(-xz * Math.sin(Math.toRadians(rotX)),
|
||||
-Math.sin(Math.toRadians(rotY)),
|
||||
xz * Math.cos(Math.toRadians(rotX)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Contract(pure = true)
|
||||
public double x() {
|
||||
@ -203,6 +238,23 @@ public final class Pos implements Point {
|
||||
return new Vec(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Pos pos = (Pos) o;
|
||||
return Double.compare(pos.x, x) == 0 &&
|
||||
Double.compare(pos.y, y) == 0 &&
|
||||
Double.compare(pos.z, z) == 0 &&
|
||||
Float.compare(pos.yaw, yaw) == 0 &&
|
||||
Float.compare(pos.pitch, pitch) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Operator {
|
||||
@NotNull Pos apply(double x, double y, double z);
|
||||
|
@ -156,19 +156,19 @@ public class EntityFinder {
|
||||
// Diff X/Y/Z
|
||||
if (dx != null || dy != null || dz != null) {
|
||||
result = result.stream().filter(entity -> {
|
||||
final Position entityPosition = entity.getPosition();
|
||||
final var entityPosition = entity.getPosition();
|
||||
if (dx != null && !MathUtils.isBetweenUnordered(
|
||||
entityPosition.getX(),
|
||||
entityPosition.x(),
|
||||
startPosition.getX(), dx))
|
||||
return false;
|
||||
|
||||
if (dy != null && !MathUtils.isBetweenUnordered(
|
||||
entityPosition.getY(),
|
||||
entityPosition.y(),
|
||||
startPosition.getY(), dy))
|
||||
return false;
|
||||
|
||||
if (dz != null && !MathUtils.isBetweenUnordered(
|
||||
entityPosition.getZ(),
|
||||
entityPosition.z(),
|
||||
startPosition.getZ(), dz))
|
||||
return false;
|
||||
|
||||
@ -231,12 +231,12 @@ public class EntityFinder {
|
||||
// RANDOM is handled below
|
||||
return 1;
|
||||
case FURTHEST:
|
||||
return startPosition.getDistance(ent1.getPosition()) >
|
||||
startPosition.getDistance(ent2.getPosition()) ?
|
||||
return startPosition.distance(ent1.getPosition()) >
|
||||
startPosition.distance(ent2.getPosition()) ?
|
||||
1 : 0;
|
||||
case NEAREST:
|
||||
return startPosition.getDistance(ent1.getPosition()) <
|
||||
startPosition.getDistance(ent2.getPosition()) ?
|
||||
return startPosition.distance(ent1.getPosition()) <
|
||||
startPosition.distance(ent2.getPosition()) ?
|
||||
1 : 0;
|
||||
}
|
||||
return 1;
|
||||
@ -346,7 +346,7 @@ public class EntityFinder {
|
||||
Collection<Player> instancePlayers = instance != null ?
|
||||
instance.getPlayers() : MinecraftServer.getConnectionManager().getOnlinePlayers();
|
||||
for (Player player : instancePlayers) {
|
||||
final double distance = player.getPosition().getDistance(startPosition);
|
||||
final double distance = player.getPosition().distance(startPosition);
|
||||
if (distance < closestDistance) {
|
||||
entity = player;
|
||||
closestDistance = distance;
|
||||
|
@ -5,9 +5,9 @@ import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
@ -18,11 +18,10 @@ public final class EntityUtils {
|
||||
|
||||
}
|
||||
|
||||
public static void forEachRange(@NotNull Instance instance, @NotNull Position position,
|
||||
public static void forEachRange(@NotNull Instance instance, @NotNull Point point,
|
||||
int viewDistance,
|
||||
@NotNull Consumer<Entity> consumer) {
|
||||
final long[] chunksInRange = ChunkUtils.getChunksInRange(position, viewDistance);
|
||||
|
||||
final long[] chunksInRange = ChunkUtils.getChunksInRange(point, viewDistance);
|
||||
for (long chunkIndex : chunksInRange) {
|
||||
final int chunkX = ChunkUtils.getChunkCoordX(chunkIndex);
|
||||
final int chunkZ = ChunkUtils.getChunkCoordZ(chunkIndex);
|
||||
@ -40,7 +39,6 @@ public final class EntityUtils {
|
||||
return false;
|
||||
|
||||
final Chunk chunk = ent1.getInstance().getChunkAt(ent1.getPosition());
|
||||
|
||||
final long[] visibleChunksEntity = ChunkUtils.getChunksInRange(ent2.getPosition(), MinecraftServer.getEntityViewDistance());
|
||||
for (long visibleChunk : visibleChunksEntity) {
|
||||
final int chunkX = ChunkUtils.getChunkCoordX(visibleChunk);
|
||||
@ -48,7 +46,6 @@ public final class EntityUtils {
|
||||
if (chunk.getChunkX() == chunkX && chunk.getChunkZ() == chunkZ)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -56,18 +53,14 @@ public final class EntityUtils {
|
||||
final Chunk chunk = entity.getChunk();
|
||||
if (chunk == null)
|
||||
return false;
|
||||
|
||||
final Position entityPosition = entity.getPosition();
|
||||
|
||||
final Pos entityPosition = entity.getPosition();
|
||||
// TODO: check entire bounding box
|
||||
final BlockPosition blockPosition = entityPosition.toBlockPosition().subtract(0, 1, 0);
|
||||
try {
|
||||
final Block block = chunk.getBlock(blockPosition);
|
||||
final Block block = chunk.getBlock(entityPosition.sub(0, 1, 0));
|
||||
return block.isSolid();
|
||||
} catch (NullPointerException e) {
|
||||
// Probably an entity at the border of an unloaded chunk
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package net.minestom.server.utils.location;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Point;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -11,7 +13,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
*
|
||||
* @param <T> the location type
|
||||
*/
|
||||
public abstract class RelativeLocation<T> {
|
||||
public abstract class RelativeLocation<T extends Point> {
|
||||
|
||||
protected T location;
|
||||
protected boolean relativeX, relativeY, relativeZ;
|
||||
@ -41,13 +43,13 @@ public abstract class RelativeLocation<T> {
|
||||
* @return the location
|
||||
*/
|
||||
public T from(@Nullable Entity entity) {
|
||||
final Position entityPosition = entity != null ? entity.getPosition() : new Position();
|
||||
final var entityPosition = entity != null ? entity.getPosition() : Pos.ZERO;
|
||||
return from(entityPosition);
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public T fromView(@Nullable Entity entity) {
|
||||
final Position entityPosition = entity != null ? entity.getPosition() : new Position();
|
||||
final var entityPosition = entity != null ? entity.getPosition() : Pos.ZERO;
|
||||
return fromView(entityPosition);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import net.minestom.server.event.player.PlayerLoginEvent;
|
||||
import net.minestom.server.instance.*;
|
||||
import net.minestom.server.instance.batch.ChunkBatch;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import net.minestom.server.world.biomes.Biome;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -31,7 +31,7 @@ public class MainDemo {
|
||||
globalEventHandler.addListener(PlayerLoginEvent.class, event -> {
|
||||
final Player player = event.getPlayer();
|
||||
event.setSpawningInstance(instanceContainer);
|
||||
player.setRespawnPoint(new Position(0, 42, 0));
|
||||
player.setRespawnPoint(new Pos(0, 42, 0));
|
||||
});
|
||||
|
||||
// Start the server on port 25565
|
||||
|
@ -30,8 +30,8 @@ import net.minestom.server.item.Material;
|
||||
import net.minestom.server.monitoring.BenchmarkManager;
|
||||
import net.minestom.server.monitoring.TickMonitor;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.coordinate.Pos;
|
||||
import net.minestom.server.utils.coordinate.Vec;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
|
||||
@ -75,11 +75,11 @@ public class PlayerInit {
|
||||
final Player player = event.getPlayer();
|
||||
ItemStack droppedItem = event.getItemStack();
|
||||
|
||||
Position position = player.getPosition().clone().add(0, 1.5f, 0);
|
||||
ItemEntity itemEntity = new ItemEntity(droppedItem, position);
|
||||
Pos playerPos = player.getPosition();
|
||||
ItemEntity itemEntity = new ItemEntity(droppedItem);
|
||||
itemEntity.setPickupDelay(Duration.of(500, TimeUnit.MILLISECOND));
|
||||
itemEntity.setInstance(player.getInstance());
|
||||
Vector velocity = player.getPosition().clone().getDirection().multiply(6);
|
||||
itemEntity.setInstance(player.getInstance(), playerPos.withY(y -> y + 1.5));
|
||||
Vec velocity = playerPos.direction().mul(6);
|
||||
itemEntity.setVelocity(velocity);
|
||||
})
|
||||
.addListener(PlayerDisconnectEvent.class, event -> System.out.println("DISCONNECTION " + event.getPlayer().getUsername()))
|
||||
@ -91,7 +91,7 @@ public class PlayerInit {
|
||||
event.setSpawningInstance(instance);
|
||||
int x = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250;
|
||||
int z = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250;
|
||||
player.setRespawnPoint(new Position(0, 42f, 0));
|
||||
player.setRespawnPoint(new Pos(0, 42f, 0));
|
||||
})
|
||||
.addListener(PlayerSpawnEvent.class, event -> {
|
||||
final Player player = event.getPlayer();
|
||||
|
Loading…
Reference in New Issue
Block a user