mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-17 16:15:32 +01:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
564d549f81
@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class BoundingBox {
|
||||
|
||||
private final Entity entity;
|
||||
private final float x, y, z;
|
||||
private final double x, y, z;
|
||||
|
||||
/**
|
||||
* Creates a {@link BoundingBox} linked to an {@link Entity} and with a specific size.
|
||||
@ -22,7 +22,7 @@ public class BoundingBox {
|
||||
* @param y the height size
|
||||
* @param z the depth size
|
||||
*/
|
||||
public BoundingBox(@NotNull Entity entity, float x, float y, float z) {
|
||||
public BoundingBox(@NotNull Entity entity, double x, double y, double z) {
|
||||
this.entity = entity;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
@ -59,30 +59,30 @@ public class BoundingBox {
|
||||
*/
|
||||
public boolean intersect(@NotNull BlockPosition blockPosition) {
|
||||
|
||||
final float offsetX = 1;
|
||||
final float x = blockPosition.getX();
|
||||
final float maxX = x + offsetX;
|
||||
final double offsetX = 1;
|
||||
final double x = blockPosition.getX();
|
||||
final double maxX = x + offsetX;
|
||||
|
||||
final boolean checkX = getMinX() < maxX && getMaxX() > x;
|
||||
if (!checkX)
|
||||
return false;
|
||||
|
||||
final float y = blockPosition.getY();
|
||||
final float maxY = y + 0.99999f;
|
||||
final double y = blockPosition.getY();
|
||||
final double maxY = y + 0.99999;
|
||||
|
||||
final boolean checkY = getMinY() < maxY && getMaxY() > y;
|
||||
if (!checkY)
|
||||
return false;
|
||||
|
||||
final float offsetZ = 1;
|
||||
final float z = blockPosition.getZ();
|
||||
final float maxZ = z + offsetZ;
|
||||
final double offsetZ = 1;
|
||||
final double z = blockPosition.getZ();
|
||||
final double maxZ = z + offsetZ;
|
||||
|
||||
// Z check
|
||||
return getMinZ() < maxZ && getMaxZ() > z;
|
||||
}
|
||||
|
||||
public boolean intersect(float x, float y, float z) {
|
||||
public boolean intersect(double x, double y, double z) {
|
||||
return (x >= getMinX() && x <= getMaxX()) &&
|
||||
(y >= getMinY() && y <= getMaxY()) &&
|
||||
(z >= getMinZ() && z <= getMaxZ());
|
||||
@ -101,7 +101,7 @@ public class BoundingBox {
|
||||
* @return a new {@link BoundingBox} expanded
|
||||
*/
|
||||
@NotNull
|
||||
public BoundingBox expand(float x, float y, float z) {
|
||||
public BoundingBox expand(double x, double y, double z) {
|
||||
return new BoundingBox(entity, this.x + x, this.y + y, this.z + z);
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ public class BoundingBox {
|
||||
* @return a new bounding box contracted
|
||||
*/
|
||||
@NotNull
|
||||
public BoundingBox contract(float x, float y, float z) {
|
||||
public BoundingBox contract(double x, double y, double z) {
|
||||
return new BoundingBox(entity, this.x - x, this.y - y, this.z - z);
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ public class BoundingBox {
|
||||
*
|
||||
* @return the width
|
||||
*/
|
||||
public float getWidth() {
|
||||
public double getWidth() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ public class BoundingBox {
|
||||
*
|
||||
* @return the height
|
||||
*/
|
||||
public float getHeight() {
|
||||
public double getHeight() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ public class BoundingBox {
|
||||
*
|
||||
* @return the depth
|
||||
*/
|
||||
public float getDepth() {
|
||||
public double getDepth() {
|
||||
return z;
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ public class BoundingBox {
|
||||
*
|
||||
* @return the min X
|
||||
*/
|
||||
public float getMinX() {
|
||||
public double getMinX() {
|
||||
return entity.getPosition().getX() - (x / 2);
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ public class BoundingBox {
|
||||
*
|
||||
* @return the max X
|
||||
*/
|
||||
public float getMaxX() {
|
||||
public double getMaxX() {
|
||||
return entity.getPosition().getX() + (x / 2);
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ public class BoundingBox {
|
||||
*
|
||||
* @return the min Y
|
||||
*/
|
||||
public float getMinY() {
|
||||
public double getMinY() {
|
||||
return entity.getPosition().getY();
|
||||
}
|
||||
|
||||
@ -177,7 +177,7 @@ public class BoundingBox {
|
||||
*
|
||||
* @return the max Y
|
||||
*/
|
||||
public float getMaxY() {
|
||||
public double getMaxY() {
|
||||
return entity.getPosition().getY() + y;
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ public class BoundingBox {
|
||||
*
|
||||
* @return the min Z
|
||||
*/
|
||||
public float getMinZ() {
|
||||
public double getMinZ() {
|
||||
return entity.getPosition().getZ() - (z / 2);
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ public class BoundingBox {
|
||||
*
|
||||
* @return the max Z
|
||||
*/
|
||||
public float getMaxZ() {
|
||||
public double getMaxZ() {
|
||||
return entity.getPosition().getZ() + (z / 2);
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ public class CollisionUtils {
|
||||
* @param corners the corners to check against
|
||||
* @return true if a collision has been found
|
||||
*/
|
||||
private static boolean stepAxis(Instance instance, Vector startPosition, Vector axis, float stepAmount, Vector positionOut, Vector... corners) {
|
||||
private static boolean stepAxis(Instance instance, Vector startPosition, Vector axis, double stepAmount, Vector positionOut, Vector... corners) {
|
||||
positionOut.copy(startPosition);
|
||||
if (corners.length == 0)
|
||||
return false; // avoid degeneracy in following computations
|
||||
@ -93,9 +93,9 @@ public class CollisionUtils {
|
||||
cornerPositions[i] = new BlockPosition(corners[i]);
|
||||
}
|
||||
|
||||
float sign = Math.signum(stepAmount);
|
||||
final double sign = Math.signum(stepAmount);
|
||||
final int blockLength = (int) stepAmount;
|
||||
final float remainingLength = stepAmount - blockLength;
|
||||
final double remainingLength = stepAmount - blockLength;
|
||||
// used to determine if 'remainingLength' should be used
|
||||
boolean collisionFound = false;
|
||||
for (int i = 0; i < Math.abs(blockLength); i++) {
|
||||
@ -115,9 +115,9 @@ public class CollisionUtils {
|
||||
}
|
||||
|
||||
// find the corner which moved the least
|
||||
float smallestDisplacement = Float.POSITIVE_INFINITY;
|
||||
double smallestDisplacement = Double.POSITIVE_INFINITY;
|
||||
for (int i = 0; i < corners.length; i++) {
|
||||
final float displacement = (float) corners[i].distance(cornersCopy[i]);
|
||||
final double displacement = corners[i].distance(cornersCopy[i]);
|
||||
if (displacement < smallestDisplacement) {
|
||||
smallestDisplacement = displacement;
|
||||
}
|
||||
@ -133,12 +133,13 @@ public class CollisionUtils {
|
||||
*
|
||||
* @param instance instance to get blocks from
|
||||
* @param axis the axis to move along
|
||||
* @param amount
|
||||
* @param cornersCopy the corners of the bounding box to consider (mutable)
|
||||
* @param cornerPositions the corners, converted to BlockPosition (mutable)
|
||||
* @return false if this method encountered a collision
|
||||
*/
|
||||
private static boolean stepOnce(Instance instance, Vector axis, float amount, Vector[] cornersCopy, BlockPosition[] cornerPositions) {
|
||||
final float sign = Math.signum(amount);
|
||||
private static boolean stepOnce(Instance instance, Vector axis, double amount, Vector[] cornersCopy, BlockPosition[] cornerPositions) {
|
||||
final double sign = Math.signum(amount);
|
||||
for (int cornerIndex = 0; cornerIndex < cornersCopy.length; cornerIndex++) {
|
||||
Vector corner = cornersCopy[cornerIndex];
|
||||
BlockPosition blockPos = cornerPositions[cornerIndex];
|
||||
|
@ -80,8 +80,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
|
||||
protected Instance instance;
|
||||
protected final Position position;
|
||||
protected float lastX, lastY, lastZ;
|
||||
protected float cacheX, cacheY, cacheZ; // Used to synchronize with #getPosition
|
||||
protected double lastX, lastY, lastZ;
|
||||
protected double cacheX, cacheY, cacheZ; // Used to synchronize with #getPosition
|
||||
protected float lastYaw, lastPitch;
|
||||
protected float cacheYaw, cachePitch;
|
||||
protected boolean onGround;
|
||||
@ -93,9 +93,9 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
// Velocity
|
||||
protected Vector velocity = new Vector(); // Movement in block per second
|
||||
|
||||
protected float gravityDragPerTick;
|
||||
protected float gravityAcceleration;
|
||||
protected float gravityTerminalVelocity;
|
||||
protected double gravityDragPerTick;
|
||||
protected double gravityAcceleration;
|
||||
protected double gravityTerminalVelocity;
|
||||
protected int gravityTickCount; // Number of tick where gravity tick was applied
|
||||
|
||||
private boolean autoViewable;
|
||||
@ -422,7 +422,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
cacheZ != position.getZ();
|
||||
final boolean viewChange = cacheYaw != position.getYaw() ||
|
||||
cachePitch != position.getPitch();
|
||||
final float distance = positionChange ? position.getDistance(cacheX, cacheY, cacheZ) : 0;
|
||||
final double distance = positionChange ? position.getDistance(cacheX, cacheY, cacheZ) : 0;
|
||||
|
||||
if (distance >= 8 || (positionChange && PlayerUtils.isNettyClient(this))) {
|
||||
// Teleport has the priority over everything else
|
||||
@ -477,16 +477,16 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
|
||||
if (applyVelocity) {
|
||||
final float tps = MinecraftServer.TICK_PER_SECOND;
|
||||
final float newX = position.getX() + velocity.getX() / tps;
|
||||
final float newY = position.getY() + velocity.getY() / tps;
|
||||
final float newZ = position.getZ() + velocity.getZ() / tps;
|
||||
final double newX = position.getX() + velocity.getX() / tps;
|
||||
final double newY = position.getY() + velocity.getY() / tps;
|
||||
final double newZ = position.getZ() + velocity.getZ() / tps;
|
||||
Position newPosition = new Position(newX, newY, newZ);
|
||||
|
||||
Vector newVelocityOut = new Vector();
|
||||
|
||||
// Gravity force
|
||||
final float gravityY = !noGravity ? Math.min(
|
||||
gravityDragPerTick + (gravityAcceleration * (float) gravityTickCount),
|
||||
final double gravityY = !noGravity ? Math.min(
|
||||
gravityDragPerTick + (gravityAcceleration * (double) gravityTickCount),
|
||||
gravityTerminalVelocity) : 0f;
|
||||
|
||||
final Vector deltaPos = new Vector(
|
||||
@ -716,7 +716,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
* @param y the bounding box Y size
|
||||
* @param z the bounding box Z size
|
||||
*/
|
||||
public void setBoundingBox(float x, float y, float z) {
|
||||
public void setBoundingBox(double x, double y, double z) {
|
||||
this.boundingBox = new BoundingBox(this, x, y, z);
|
||||
}
|
||||
|
||||
@ -815,7 +815,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
*
|
||||
* @return the gravity drag per tick in block
|
||||
*/
|
||||
public float getGravityDragPerTick() {
|
||||
public double getGravityDragPerTick() {
|
||||
return gravityDragPerTick;
|
||||
}
|
||||
|
||||
@ -824,7 +824,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
*
|
||||
* @return the gravity acceleration in block
|
||||
*/
|
||||
public float getGravityAcceleration() {
|
||||
public double getGravityAcceleration() {
|
||||
return gravityAcceleration;
|
||||
}
|
||||
|
||||
@ -833,7 +833,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
*
|
||||
* @return the maximum gravity velocity in block
|
||||
*/
|
||||
public float getGravityTerminalVelocity() {
|
||||
public double getGravityTerminalVelocity() {
|
||||
return gravityTerminalVelocity;
|
||||
}
|
||||
|
||||
@ -854,7 +854,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
* @param gravityTerminalVelocity the gravity terminal velocity (maximum) in block
|
||||
* @see <a href="https://minecraft.gamepedia.com/Entity#Motion_of_entities">Entities motion</a>
|
||||
*/
|
||||
public void setGravity(float gravityDragPerTick, float gravityAcceleration, float gravityTerminalVelocity) {
|
||||
public void setGravity(double gravityDragPerTick, double gravityAcceleration, double gravityTerminalVelocity) {
|
||||
this.gravityDragPerTick = gravityDragPerTick;
|
||||
this.gravityAcceleration = gravityAcceleration;
|
||||
this.gravityTerminalVelocity = gravityTerminalVelocity;
|
||||
@ -866,7 +866,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
* @param entity the entity to get the distance from
|
||||
* @return the distance between this and {@code entity}
|
||||
*/
|
||||
public float getDistance(@NotNull Entity entity) {
|
||||
public double getDistance(@NotNull Entity entity) {
|
||||
return getPosition().getDistance(entity.getPosition());
|
||||
}
|
||||
|
||||
@ -1102,7 +1102,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
* @param y new position Y
|
||||
* @param z new position Z
|
||||
*/
|
||||
public void refreshPosition(float x, float y, float z) {
|
||||
public void refreshPosition(double x, double y, double z) {
|
||||
position.setX(x);
|
||||
position.setY(y);
|
||||
position.setZ(z);
|
||||
@ -1147,7 +1147,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
|
||||
/**
|
||||
* @param position the new position
|
||||
* @see #refreshPosition(float, float, float)
|
||||
* @see #refreshPosition(double, double, double)
|
||||
*/
|
||||
public void refreshPosition(@NotNull Position position) {
|
||||
refreshPosition(position.getX(), position.getY(), position.getZ());
|
||||
@ -1237,8 +1237,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
*
|
||||
* @return the entity eye height
|
||||
*/
|
||||
public float getEyeHeight() {
|
||||
return boundingBox.getHeight() * 0.85f;
|
||||
public double getEyeHeight() {
|
||||
return boundingBox.getHeight() * 0.85;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,12 +3,13 @@ package net.minestom.server.entity;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.network.packet.server.play.SpawnExperienceOrbPacket;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class ExperienceOrb extends Entity {
|
||||
|
||||
private short experienceCount;
|
||||
@ -132,7 +133,7 @@ public class ExperienceOrb extends Entity {
|
||||
Player closest = entity.getInstance()
|
||||
.getPlayers()
|
||||
.stream()
|
||||
.min((a, b) -> Float.compare(a.getDistance(entity), b.getDistance(entity)))
|
||||
.min(Comparator.comparingDouble(a -> a.getDistance(entity)))
|
||||
.orElse(null);
|
||||
if (closest == null) return null;
|
||||
if (closest.getDistance(entity) > maxDistance) return null;
|
||||
|
@ -27,7 +27,6 @@ import net.minestom.server.utils.block.BlockIterator;
|
||||
import net.minestom.server.utils.time.CooldownUtils;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -451,7 +450,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoundingBox(float x, float y, float z) {
|
||||
public void setBoundingBox(double x, double y, double z) {
|
||||
super.setBoundingBox(x, y, z);
|
||||
this.expandedBoundingBox = getBoundingBox().expand(1, 0.5f, 1);
|
||||
}
|
||||
|
@ -169,7 +169,8 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
// Position synchronization with viewers
|
||||
private long lastPlayerSynchronizationTime;
|
||||
private float lastPlayerSyncX, lastPlayerSyncY, lastPlayerSyncZ, lastPlayerSyncYaw, lastPlayerSyncPitch;
|
||||
private double lastPlayerSyncX, lastPlayerSyncY, lastPlayerSyncZ;
|
||||
private float lastPlayerSyncYaw, lastPlayerSyncPitch;
|
||||
|
||||
// Experience orb pickup
|
||||
protected UpdateOption experiencePickupCooldown = new UpdateOption(10, TimeUnit.TICK);
|
||||
@ -1615,7 +1616,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
// Manage already viewable entities
|
||||
this.viewableEntities.forEach(entity -> {
|
||||
final float distance = entity.getDistance(this);
|
||||
final double distance = entity.getDistance(this);
|
||||
if (distance > maximalDistance) {
|
||||
// Entity shouldn't be viewable anymore
|
||||
if (isAutoViewable()) {
|
||||
|
@ -83,7 +83,7 @@ public class FollowTargetGoal extends GoalSelector {
|
||||
entityCreature.setPathTo(null);
|
||||
}
|
||||
|
||||
private float getDistance(@NotNull Position a, @NotNull Position b) {
|
||||
private double getDistance(@NotNull Position a, @NotNull Position b) {
|
||||
return MathUtils.square(a.getX() - b.getX()) +
|
||||
MathUtils.square(a.getZ() - b.getZ());
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class ClosestEntityTarget extends TargetSelector {
|
||||
final List<Chunk> chunks = getNeighbours(instance, currentChunk.getChunkX(), currentChunk.getChunkZ());
|
||||
|
||||
Entity entity = null;
|
||||
float distance = Float.MAX_VALUE;
|
||||
double distance = Double.MAX_VALUE;
|
||||
|
||||
for (Chunk chunk : chunks) {
|
||||
final Set<Entity> entities = instance.getChunkEntities(chunk);
|
||||
@ -76,7 +76,7 @@ public class ClosestEntityTarget extends TargetSelector {
|
||||
}
|
||||
|
||||
// Check distance
|
||||
final float d = entityCreature.getDistance(ent);
|
||||
final double d = entityCreature.getDistance(ent);
|
||||
if ((entity == null || d < distance) && d < range) {
|
||||
entity = ent;
|
||||
distance = d;
|
||||
|
@ -12,7 +12,6 @@ import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.utils.position.PositionUtils;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -29,32 +28,32 @@ public interface NavigableEntity {
|
||||
* @param direction the targeted position
|
||||
* @param speed define how far the entity will move
|
||||
*/
|
||||
default void moveTowards(@NotNull Position direction, float speed) {
|
||||
default void moveTowards(@NotNull Position direction, double speed) {
|
||||
|
||||
final Position position = getNavigableEntity().getPosition();
|
||||
|
||||
final float currentX = position.getX();
|
||||
final float currentY = position.getY();
|
||||
final float currentZ = position.getZ();
|
||||
final double currentX = position.getX();
|
||||
final double currentY = position.getY();
|
||||
final double currentZ = position.getZ();
|
||||
|
||||
final float targetX = direction.getX();
|
||||
final float targetY = direction.getY();
|
||||
final float targetZ = direction.getZ();
|
||||
final double targetX = direction.getX();
|
||||
final double targetY = direction.getY();
|
||||
final double targetZ = direction.getZ();
|
||||
|
||||
final float dx = targetX - currentX;
|
||||
final float dy = targetY - currentY;
|
||||
final float dz = targetZ - currentZ;
|
||||
final double dx = targetX - currentX;
|
||||
final double dy = targetY - currentY;
|
||||
final double dz = targetZ - currentZ;
|
||||
|
||||
// the purpose of these few lines is to slow down entities when they reach their destination
|
||||
final float distSquared = dx * dx + dy * dy + dz * dz;
|
||||
final double distSquared = dx * dx + dy * dy + dz * dz;
|
||||
if (speed > distSquared) {
|
||||
speed = distSquared;
|
||||
}
|
||||
|
||||
final float radians = (float) Math.atan2(dz, dx);
|
||||
final float speedX = (float) (Math.cos(radians) * speed);
|
||||
final float speedY = dy * speed;
|
||||
final float speedZ = (float) (Math.sin(radians) * speed);
|
||||
final double radians = Math.atan2(dz, dx);
|
||||
final double speedX = Math.cos(radians) * speed;
|
||||
final double speedY = dy * speed;
|
||||
final double speedZ = Math.sin(radians) * speed;
|
||||
|
||||
// Update 'position' view
|
||||
PositionUtils.lookAlong(position, dx, direction.getY(), dz);
|
||||
|
@ -189,13 +189,10 @@ public class PFPathingEntity implements IPathingEntity {
|
||||
|
||||
@Override
|
||||
public void moveTo(Vec3d position, Passibility passibility, Gravitation gravitation) {
|
||||
final float x = (float) position.x;
|
||||
final float y = (float) position.y;
|
||||
final float z = (float) position.z;
|
||||
this.targetPosition = new Position(x, y, z);
|
||||
this.targetPosition = new Position(position.x, position.y, position.z);
|
||||
|
||||
final float entityY = entity.getPosition().getY();
|
||||
if (entityY < y) {
|
||||
final double entityY = entity.getPosition().getY();
|
||||
if (entityY < targetPosition.getY()) {
|
||||
navigableEntity.jump(1);
|
||||
}
|
||||
}
|
||||
@ -208,12 +205,12 @@ public class PFPathingEntity implements IPathingEntity {
|
||||
|
||||
@Override
|
||||
public float width() {
|
||||
return entity.getBoundingBox().getWidth();
|
||||
return (float) entity.getBoundingBox().getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float height() {
|
||||
return entity.getBoundingBox().getHeight();
|
||||
return (float) entity.getBoundingBox().getHeight();
|
||||
}
|
||||
|
||||
private float getAttributeValue(@NotNull Attribute attribute) {
|
||||
|
@ -311,15 +311,15 @@ public class EntityArmorStand extends ObjectEntity implements EquipmentHandler {
|
||||
}
|
||||
|
||||
private float getRotationX(Vector vector) {
|
||||
return vector != null ? vector.getX() : 0;
|
||||
return vector != null ? (float) vector.getX() : 0;
|
||||
}
|
||||
|
||||
private float getRotationY(Vector vector) {
|
||||
return vector != null ? vector.getY() : 0;
|
||||
return vector != null ? (float) vector.getY() : 0;
|
||||
}
|
||||
|
||||
private float getRotationZ(Vector vector) {
|
||||
return vector != null ? vector.getZ() : 0;
|
||||
return vector != null ? (float) vector.getZ() : 0;
|
||||
}
|
||||
|
||||
// Equipments
|
||||
|
@ -62,7 +62,7 @@ public class EntityZombie extends EntityCreature implements Monster {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getEyeHeight() {
|
||||
return isBaby() ? 0.93f : 1.74f;
|
||||
public double getEyeHeight() {
|
||||
return isBaby() ? 0.93 : 1.74;
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public class EntityZombifiedPiglin extends EntityCreature implements Monster {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getEyeHeight() {
|
||||
return isBaby() ? 0.93f : 1.74f;
|
||||
public double getEyeHeight() {
|
||||
return isBaby() ? 0.93 : 1.74;
|
||||
}
|
||||
}
|
||||
|
@ -657,8 +657,8 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
|
||||
* @param z the Z position
|
||||
* @return the block state id at the position
|
||||
*/
|
||||
public short getBlockStateId(float x, float y, float z) {
|
||||
return getBlockStateId(Math.round(x), Math.round(y), Math.round(z));
|
||||
public short getBlockStateId(double x, double y, double z) {
|
||||
return getBlockStateId((int) Math.round(x), (int) Math.round(y), (int) Math.round(z));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -785,7 +785,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
|
||||
* @return the chunk at the given position, null if not loaded
|
||||
*/
|
||||
@Nullable
|
||||
public Chunk getChunkAt(float x, float z) {
|
||||
public Chunk getChunkAt(double x, double z) {
|
||||
final int chunkX = ChunkUtils.getChunkCoordinate((int) Math.floor(x));
|
||||
final int chunkZ = ChunkUtils.getChunkCoordinate((int) Math.floor(z));
|
||||
return getChunk(chunkX, chunkZ);
|
||||
|
@ -155,13 +155,13 @@ public final class InstanceManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets instance by given UUID.
|
||||
* Gets an instance by the given UUID.
|
||||
*
|
||||
* @param uuid UUID of the instance
|
||||
* @return {@link Optional#empty()} if instance is not found
|
||||
* @return the instance with the given UUID, null if not found
|
||||
*/
|
||||
@NotNull
|
||||
public @Nullable Instance getInstance(UUID uuid) {
|
||||
@Nullable
|
||||
public Instance getInstance(@NotNull UUID uuid) {
|
||||
Optional<Instance> instance = getInstances()
|
||||
.stream()
|
||||
.filter(someInstance -> someInstance.getUniqueId().equals(uuid))
|
||||
|
@ -20,9 +20,9 @@ public class PlayerPositionListener {
|
||||
|
||||
public static void playerLookListener(ClientPlayerRotationPacket packet, Player player) {
|
||||
final Position playerPosition = player.getPosition();
|
||||
final float x = playerPosition.getX();
|
||||
final float y = playerPosition.getY();
|
||||
final float z = playerPosition.getZ();
|
||||
final double x = playerPosition.getX();
|
||||
final double y = playerPosition.getY();
|
||||
final double z = playerPosition.getZ();
|
||||
final float yaw = packet.yaw;
|
||||
final float pitch = packet.pitch;
|
||||
final boolean onGround = packet.onGround;
|
||||
@ -31,26 +31,24 @@ public class PlayerPositionListener {
|
||||
|
||||
public static void playerPositionListener(ClientPlayerPositionPacket packet, Player player) {
|
||||
final Position playerPosition = player.getPosition();
|
||||
final float x = (float) packet.x;
|
||||
final float y = (float) packet.y;
|
||||
final float z = (float) packet.z;
|
||||
final float yaw = playerPosition.getYaw();
|
||||
final float pitch = playerPosition.getPitch();
|
||||
final boolean onGround = packet.onGround;
|
||||
processMovement(player, x, y, z, yaw, pitch, onGround);
|
||||
processMovement(player,
|
||||
packet.x, packet.y, packet.z,
|
||||
yaw, pitch, onGround);
|
||||
}
|
||||
|
||||
public static void playerPositionAndLookListener(ClientPlayerPositionAndRotationPacket packet, Player player) {
|
||||
final float x = (float) packet.x;
|
||||
final float y = (float) packet.y;
|
||||
final float z = (float) packet.z;
|
||||
final float yaw = packet.yaw;
|
||||
final float pitch = packet.pitch;
|
||||
final boolean onGround = packet.onGround;
|
||||
processMovement(player, x, y, z, yaw, pitch, onGround);
|
||||
processMovement(player,
|
||||
packet.x, packet.y, packet.z,
|
||||
yaw, pitch, onGround);
|
||||
}
|
||||
|
||||
private static void processMovement(@NotNull Player player, float x, float y, float z,
|
||||
private static void processMovement(@NotNull Player player, double x, double y, double z,
|
||||
float yaw, float pitch, boolean onGround) {
|
||||
final Instance instance = player.getInstance();
|
||||
|
||||
@ -60,7 +58,7 @@ public class PlayerPositionListener {
|
||||
}
|
||||
|
||||
// Prevent the player from moving during a teleport
|
||||
final float distance = player.getPosition().getDistance(x, y, z);
|
||||
final double distance = player.getPosition().getDistance(x, y, z);
|
||||
final int chunkRange = player.getChunkRange() * Chunk.CHUNK_SECTION_SIZE;
|
||||
if (distance >= chunkRange) {
|
||||
return;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.minestom.server.scoreboard;
|
||||
|
||||
import com.google.common.collect.Queues;
|
||||
import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet;
|
||||
import net.minestom.server.chat.ChatParser;
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
@ -16,8 +15,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -37,7 +34,7 @@ public class Sidebar implements Scoreboard {
|
||||
private static final AtomicInteger COUNTER = new AtomicInteger();
|
||||
|
||||
/**
|
||||
* <b>WARNING:</b> You shouldn't create scoreboards/teams with the same prefixes as those
|
||||
* <b>WARNING:</b> You should NOT create any scoreboards/teams with the same prefixes as those
|
||||
*/
|
||||
private static final String SCOREBOARD_PREFIX = "sb-";
|
||||
private static final String TEAM_PREFIX = "sbt-";
|
||||
@ -48,9 +45,8 @@ public class Sidebar implements Scoreboard {
|
||||
private static final int MAX_LINES_COUNT = 15;
|
||||
|
||||
private final Set<Player> viewers = new CopyOnWriteArraySet<>();
|
||||
private final Set<Player> unmodifiableViewers = Collections.unmodifiableSet(viewers);
|
||||
|
||||
private final Queue<ScoreboardLine> lines = Queues.newConcurrentLinkedQueue();
|
||||
private final Set<ScoreboardLine> lines = new CopyOnWriteArraySet<>();
|
||||
private final IntLinkedOpenHashSet availableColors = new IntLinkedOpenHashSet();
|
||||
|
||||
private final String objectiveName;
|
||||
@ -164,26 +160,33 @@ public class Sidebar implements Scoreboard {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link Set} containing all the registered lines.
|
||||
*
|
||||
* @return an unmodifiable set containing the sidebar's lines
|
||||
*/
|
||||
@NotNull
|
||||
public Set<ScoreboardLine> getLines() {
|
||||
return Collections.unmodifiableSet(lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@link ScoreboardLine} through the given identifier
|
||||
*
|
||||
* @param id the identifier of the {@link ScoreboardLine}
|
||||
*/
|
||||
public void removeLine(@NotNull String id) {
|
||||
synchronized (lines) {
|
||||
Iterator<ScoreboardLine> iterator = lines.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ScoreboardLine line = iterator.next();
|
||||
this.lines.removeIf(line -> {
|
||||
if (line.id.equals(id)) {
|
||||
|
||||
// Remove the line for current viewers
|
||||
sendPacketsToViewers(line.getScoreCreationPacket(objectiveName), line.sidebarTeam.getDestructionPacket());
|
||||
|
||||
line.returnName(availableColors);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -221,7 +224,7 @@ public class Sidebar implements Scoreboard {
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Player> getViewers() {
|
||||
return unmodifiableViewers;
|
||||
return Collections.unmodifiableSet(viewers);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -258,7 +261,7 @@ public class Sidebar implements Scoreboard {
|
||||
*/
|
||||
private SidebarTeam sidebarTeam;
|
||||
|
||||
public ScoreboardLine(String id, JsonMessage content, int line) {
|
||||
public ScoreboardLine(@NotNull String id, @NotNull JsonMessage content, int line) {
|
||||
this.id = id;
|
||||
this.content = content;
|
||||
this.line = line;
|
||||
@ -271,6 +274,7 @@ public class Sidebar implements Scoreboard {
|
||||
*
|
||||
* @return the line identifier
|
||||
*/
|
||||
@NotNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
@ -280,6 +284,7 @@ public class Sidebar implements Scoreboard {
|
||||
*
|
||||
* @return The line content
|
||||
*/
|
||||
@NotNull
|
||||
public JsonMessage getContent() {
|
||||
return sidebarTeam == null ? content : sidebarTeam.getPrefix();
|
||||
}
|
||||
@ -473,7 +478,7 @@ public class Sidebar implements Scoreboard {
|
||||
*
|
||||
* @param prefix The refreshed prefix
|
||||
*/
|
||||
private void refreshPrefix(JsonMessage prefix) {
|
||||
private void refreshPrefix(@NotNull JsonMessage prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class BlockPosition implements PublicCloneable<BlockPosition> {
|
||||
* @param y the block Y
|
||||
* @param z the block Z
|
||||
*/
|
||||
public BlockPosition(float x, float y, float z) {
|
||||
public BlockPosition(double x, double y, double z) {
|
||||
final int castedY = (int) y;
|
||||
|
||||
this.x = (int) Math.floor(x);
|
||||
@ -50,7 +50,7 @@ public class BlockPosition implements PublicCloneable<BlockPosition> {
|
||||
* Creates a new {@link BlockPosition} from a {@link Vector}.
|
||||
*
|
||||
* @param position the position vector
|
||||
* @see #BlockPosition(float, float, float)
|
||||
* @see #BlockPosition(double, double, double)
|
||||
*/
|
||||
public BlockPosition(@NotNull Vector position) {
|
||||
this(position.getX(), position.getY(), position.getZ());
|
||||
|
@ -14,6 +14,10 @@ public final class MathUtils {
|
||||
return num * num;
|
||||
}
|
||||
|
||||
public static double square(double num) {
|
||||
return num * num;
|
||||
}
|
||||
|
||||
public static double round(double value, int places) {
|
||||
if (places < 0) throw new IllegalArgumentException();
|
||||
|
||||
@ -55,10 +59,22 @@ public final class MathUtils {
|
||||
return number >= min && number <= max;
|
||||
}
|
||||
|
||||
public static boolean isBetween(double number, double min, double max) {
|
||||
return number >= min && number <= max;
|
||||
}
|
||||
|
||||
public static boolean isBetween(float number, float min, float max) {
|
||||
return number >= min && number <= max;
|
||||
}
|
||||
|
||||
public static boolean isBetweenUnordered(double number, double compare1, double compare2) {
|
||||
if (compare1 > compare2) {
|
||||
return isBetween(number, compare2, compare1);
|
||||
} else {
|
||||
return isBetween(number, compare1, compare2);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBetweenUnordered(float number, float compare1, float compare2) {
|
||||
if (compare1 > compare2) {
|
||||
return isBetween(number, compare2, compare1);
|
||||
|
@ -13,10 +13,10 @@ import java.util.Objects;
|
||||
*/
|
||||
public class Position implements PublicCloneable<Position> {
|
||||
|
||||
private float x, y, z;
|
||||
private double x, y, z;
|
||||
private float yaw, pitch;
|
||||
|
||||
public Position(float x, float y, float z, float yaw, float pitch) {
|
||||
public Position(double x, double y, double z, float yaw, float pitch) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
@ -24,7 +24,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public Position(float x, float y, float z) {
|
||||
public Position(double x, double y, double z) {
|
||||
this(x, y, z, 0, 0);
|
||||
}
|
||||
|
||||
@ -40,7 +40,8 @@ public class Position implements PublicCloneable<Position> {
|
||||
* @param z the Z offset
|
||||
* @return the same object position
|
||||
*/
|
||||
public Position add(float x, float y, float z) {
|
||||
@NotNull
|
||||
public Position add(double x, double y, double z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
@ -53,7 +54,8 @@ public class Position implements PublicCloneable<Position> {
|
||||
* @param position the position to add to this
|
||||
* @return the same object position
|
||||
*/
|
||||
public Position add(Position position) {
|
||||
@NotNull
|
||||
public Position add(@NotNull Position position) {
|
||||
this.x += position.x;
|
||||
this.y += position.y;
|
||||
this.z += position.z;
|
||||
@ -68,15 +70,16 @@ public class Position implements PublicCloneable<Position> {
|
||||
* @param z the Z offset
|
||||
* @return the same object position
|
||||
*/
|
||||
public Position subtract(float x, float y, float z) {
|
||||
@NotNull
|
||||
public Position subtract(double x, double y, double z) {
|
||||
this.x -= x;
|
||||
this.y -= y;
|
||||
this.z -= z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float getDistance(float x, float y, float z) {
|
||||
return (float) Math.sqrt(MathUtils.square(x - getX()) +
|
||||
public double getDistance(double x, double y, double z) {
|
||||
return Math.sqrt(MathUtils.square(x - getX()) +
|
||||
MathUtils.square(y - getY()) +
|
||||
MathUtils.square(z - getZ()));
|
||||
}
|
||||
@ -89,7 +92,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
* @param position the second position
|
||||
* @return the distance between {@code this} and {@code position}
|
||||
*/
|
||||
public float getDistance(@NotNull Position position) {
|
||||
public double getDistance(@NotNull Position position) {
|
||||
return getDistance(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
@ -99,7 +102,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
* @param position the second position
|
||||
* @return the squared distance between {@code this} and {@code position}
|
||||
*/
|
||||
public float getDistanceSquared(@NotNull Position position) {
|
||||
public double getDistanceSquared(@NotNull Position position) {
|
||||
return MathUtils.square(getX() - position.getX()) +
|
||||
MathUtils.square(getY() - position.getY()) +
|
||||
MathUtils.square(getZ() - position.getZ());
|
||||
@ -123,8 +126,8 @@ public class Position implements PublicCloneable<Position> {
|
||||
|
||||
final double xz = Math.cos(Math.toRadians(rotY));
|
||||
|
||||
vector.setX((float) (-xz * Math.sin(Math.toRadians(rotX))));
|
||||
vector.setZ((float) (xz * Math.cos(Math.toRadians(rotX))));
|
||||
vector.setX((-xz * Math.sin(Math.toRadians(rotX))));
|
||||
vector.setZ((xz * Math.cos(Math.toRadians(rotX))));
|
||||
|
||||
return vector;
|
||||
}
|
||||
@ -144,8 +147,8 @@ public class Position implements PublicCloneable<Position> {
|
||||
* z = Adj
|
||||
*/
|
||||
final double _2PI = 2 * Math.PI;
|
||||
final float x = vector.getX();
|
||||
final float z = vector.getZ();
|
||||
final double x = vector.getX();
|
||||
final double z = vector.getZ();
|
||||
|
||||
if (x == 0 && z == 0) {
|
||||
pitch = vector.getY() > 0 ? -90 : 90;
|
||||
@ -155,9 +158,9 @@ public class Position implements PublicCloneable<Position> {
|
||||
final double theta = Math.atan2(-x, z);
|
||||
yaw = (float) Math.toDegrees((theta + _2PI) % _2PI);
|
||||
|
||||
final float x2 = MathUtils.square(x);
|
||||
final float z2 = MathUtils.square(z);
|
||||
final float xz = (float) Math.sqrt(x2 + z2);
|
||||
final double x2 = MathUtils.square(x);
|
||||
final double z2 = MathUtils.square(z);
|
||||
final double xz = Math.sqrt(x2 + z2);
|
||||
pitch = (float) Math.toDegrees(Math.atan(-vector.getY() / xz));
|
||||
|
||||
return this;
|
||||
@ -228,11 +231,11 @@ public class Position implements PublicCloneable<Position> {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Position position = (Position) o;
|
||||
return Float.compare(position.x, x) == 0 &&
|
||||
Float.compare(position.y, y) == 0 &&
|
||||
Float.compare(position.z, z) == 0 &&
|
||||
Float.compare(position.yaw, yaw) == 0 &&
|
||||
Float.compare(position.pitch, pitch) == 0;
|
||||
return Double.compare(position.x, x) == 0 &&
|
||||
Double.compare(position.y, y) == 0 &&
|
||||
Double.compare(position.z, z) == 0 &&
|
||||
Double.compare(position.yaw, yaw) == 0 &&
|
||||
Double.compare(position.pitch, pitch) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,9 +245,9 @@ public class Position implements PublicCloneable<Position> {
|
||||
* @return true if the two positions are similar
|
||||
*/
|
||||
public boolean isSimilar(@NotNull Position position) {
|
||||
return Float.compare(position.x, x) == 0 &&
|
||||
Float.compare(position.y, y) == 0 &&
|
||||
Float.compare(position.z, z) == 0;
|
||||
return Double.compare(position.x, x) == 0 &&
|
||||
Double.compare(position.y, y) == 0 &&
|
||||
Double.compare(position.z, z) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -284,7 +287,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
*
|
||||
* @return the position X
|
||||
*/
|
||||
public float getX() {
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -293,7 +296,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
*
|
||||
* @param x the new position X
|
||||
*/
|
||||
public void setX(float x) {
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
@ -302,7 +305,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
*
|
||||
* @return the position Y
|
||||
*/
|
||||
public float getY() {
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@ -311,7 +314,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
*
|
||||
* @param y the new position Y
|
||||
*/
|
||||
public void setY(float y) {
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@ -320,7 +323,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
*
|
||||
* @return the position Z
|
||||
*/
|
||||
public float getZ() {
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
@ -329,7 +332,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
*
|
||||
* @param z the new position Z
|
||||
*/
|
||||
public void setZ(float z) {
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@ -374,6 +377,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
*
|
||||
* @return the converted {@link BlockPosition}
|
||||
*/
|
||||
@NotNull
|
||||
public BlockPosition toBlockPosition() {
|
||||
return new BlockPosition(x, y, z);
|
||||
}
|
||||
@ -383,6 +387,7 @@ public class Position implements PublicCloneable<Position> {
|
||||
*
|
||||
* @return the converted {@link Vector}
|
||||
*/
|
||||
@NotNull
|
||||
public Vector toVector() {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minestom.server.utils;
|
||||
|
||||
import com.google.common.primitives.Doubles;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.utils.clone.PublicCloneable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -8,7 +9,7 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
|
||||
private static final double epsilon = 0.000001;
|
||||
|
||||
protected float x, y, z;
|
||||
protected double x, y, z;
|
||||
|
||||
public Vector() {
|
||||
this.x = 0;
|
||||
@ -16,7 +17,7 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
this.z = 0;
|
||||
}
|
||||
|
||||
public Vector(float x, float y, float z) {
|
||||
public Vector(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
@ -31,7 +32,7 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector add(float x, float y, float z) {
|
||||
public Vector add(double x, double y, double z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
@ -53,7 +54,7 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector subtract(float x, float y, float z) {
|
||||
public Vector subtract(double x, double y, double z) {
|
||||
this.x -= x;
|
||||
this.y -= y;
|
||||
this.z -= z;
|
||||
@ -126,6 +127,15 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
return Math.sqrt(MathUtils.square(x) + MathUtils.square(y) + MathUtils.square(z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the magnitude of the vector squared.
|
||||
*
|
||||
* @return the magnitude
|
||||
*/
|
||||
public double lengthSquared() {
|
||||
return MathUtils.square(x) + MathUtils.square(y) + MathUtils.square(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance between this vector and another. The value of this
|
||||
* method is not cached and uses a costly square-root function, so do not
|
||||
@ -150,6 +160,18 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
return MathUtils.square(x - o.x) + MathUtils.square(y - o.y) + MathUtils.square(z - o.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the angle between this vector and another in radians.
|
||||
*
|
||||
* @param other The other vector
|
||||
* @return angle in radians
|
||||
*/
|
||||
public float angle(@NotNull Vector other) {
|
||||
double dot = Doubles.constrainToRange(dot(other) / (length() * other.length()), -1.0, 1.0);
|
||||
|
||||
return (float) Math.acos(dot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs scalar multiplication, multiplying all components with a
|
||||
* scalar.
|
||||
@ -195,6 +217,57 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the dot product of this vector with another. The dot product
|
||||
* is defined as x1*x2+y1*y2+z1*z2. The returned value is a scalar.
|
||||
*
|
||||
* @param other The other vector
|
||||
* @return dot product
|
||||
*/
|
||||
public double dot(@NotNull Vector other) {
|
||||
return x * other.x + y * other.y + z * other.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the cross product of this vector with another. The cross
|
||||
* product is defined as:
|
||||
* <ul>
|
||||
* <li>x = y1 * z2 - y2 * z1
|
||||
* <li>y = z1 * x2 - z2 * x1
|
||||
* <li>z = x1 * y2 - x2 * y1
|
||||
* </ul>
|
||||
*
|
||||
* @param o The other vector
|
||||
* @return the same vector
|
||||
*/
|
||||
@NotNull
|
||||
public Vector crossProduct(@NotNull Vector o) {
|
||||
this.x = y * o.z - o.y * z;
|
||||
this.y = z * o.x - o.z * x;
|
||||
this.z = x * o.y - o.x * y;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the cross product of this vector with another without mutating
|
||||
* the original. The cross product is defined as:
|
||||
* <ul>
|
||||
* <li>x = y1 * z2 - y2 * z1
|
||||
* <li>y = z1 * x2 - z2 * x1
|
||||
* <li>z = x1 * y2 - x2 * y1
|
||||
* </ul>
|
||||
*
|
||||
* @param o The other vector
|
||||
* @return a new vector
|
||||
*/
|
||||
@NotNull
|
||||
public Vector getCrossProduct(@NotNull Vector o) {
|
||||
final double x = this.y * o.z - o.y * this.z;
|
||||
final double y = this.z * o.x - o.z * this.x;
|
||||
final double z = this.x * o.y - o.x * this.y;
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this vector to a unit vector (a vector with length of 1).
|
||||
*
|
||||
@ -223,6 +296,145 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if a vector is normalized
|
||||
*
|
||||
* @return whether the vector is normalised
|
||||
*/
|
||||
public boolean isNormalized() {
|
||||
return Math.abs(this.lengthSquared() - 1) < getEpsilon();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the vector around the x axis.
|
||||
* <p>
|
||||
* This piece of math is based on the standard rotation matrix for vectors
|
||||
* in three dimensional space. This matrix can be found here:
|
||||
* <a href="https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations">Rotation
|
||||
* Matrix</a>.
|
||||
*
|
||||
* @param angle the angle to rotate the vector about. This angle is passed
|
||||
* in radians
|
||||
* @return the same vector
|
||||
*/
|
||||
@NotNull
|
||||
public Vector rotateAroundX(double angle) {
|
||||
double angleCos = Math.cos(angle);
|
||||
double angleSin = Math.sin(angle);
|
||||
|
||||
this.y = angleCos * getY() - angleSin * getZ();
|
||||
this.z = angleSin * getY() + angleCos * getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the vector around the y axis.
|
||||
* <p>
|
||||
* This piece of math is based on the standard rotation matrix for vectors
|
||||
* in three dimensional space. This matrix can be found here:
|
||||
* <a href="https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations">Rotation
|
||||
* Matrix</a>.
|
||||
*
|
||||
* @param angle the angle to rotate the vector about. This angle is passed
|
||||
* in radians
|
||||
* @return the same vector
|
||||
*/
|
||||
@NotNull
|
||||
public Vector rotateAroundY(double angle) {
|
||||
double angleCos = Math.cos(angle);
|
||||
double angleSin = Math.sin(angle);
|
||||
|
||||
this.x = angleCos * getX() + angleSin * getZ();
|
||||
this.z = -angleSin * getX() + angleCos * getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the vector around the z axis
|
||||
* <p>
|
||||
* This piece of math is based on the standard rotation matrix for vectors
|
||||
* in three dimensional space. This matrix can be found here:
|
||||
* <a href="https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations">Rotation
|
||||
* Matrix</a>.
|
||||
*
|
||||
* @param angle the angle to rotate the vector about. This angle is passed
|
||||
* in radians
|
||||
* @return the same vector
|
||||
*/
|
||||
@NotNull
|
||||
public Vector rotateAroundZ(double angle) {
|
||||
double angleCos = Math.cos(angle);
|
||||
double angleSin = Math.sin(angle);
|
||||
|
||||
this.x = angleCos * getX() - angleSin * getY();
|
||||
this.y = angleSin * getX() + angleCos * getY();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the vector around a given arbitrary axis in 3 dimensional space.
|
||||
*
|
||||
* <p>
|
||||
* Rotation will follow the general Right-Hand-Rule, which means rotation
|
||||
* will be counterclockwise when the axis is pointing towards the observer.
|
||||
* <p>
|
||||
* This method will always make sure the provided axis is a unit vector, to
|
||||
* not modify the length of the vector when rotating. If you are experienced
|
||||
* with the scaling of a non-unit axis vector, you can use
|
||||
* {@link Vector#rotateAroundNonUnitAxis(Vector, double)}.
|
||||
*
|
||||
* @param axis the axis to rotate the vector around. If the passed vector is
|
||||
* not of length 1, it gets copied and normalized before using it for the
|
||||
* rotation. Please use {@link Vector#normalize()} on the instance before
|
||||
* passing it to this method
|
||||
* @param angle the angle to rotate the vector around the axis
|
||||
* @return the same vector
|
||||
*/
|
||||
@NotNull
|
||||
public Vector rotateAroundAxis(@NotNull Vector axis, double angle) throws IllegalArgumentException {
|
||||
return rotateAroundNonUnitAxis(axis.isNormalized() ? axis : axis.clone().normalize(), angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the vector around a given arbitrary axis in 3 dimensional space.
|
||||
*
|
||||
* <p>
|
||||
* Rotation will follow the general Right-Hand-Rule, which means rotation
|
||||
* will be counterclockwise when the axis is pointing towards the observer.
|
||||
* <p>
|
||||
* Note that the vector length will change accordingly to the axis vector
|
||||
* length. If the provided axis is not a unit vector, the rotated vector
|
||||
* will not have its previous length. The scaled length of the resulting
|
||||
* vector will be related to the axis vector. If you are not perfectly sure
|
||||
* about the scaling of the vector, use
|
||||
* {@link Vector#rotateAroundAxis(Vector, double)}
|
||||
*
|
||||
* @param axis the axis to rotate the vector around.
|
||||
* @param angle the angle to rotate the vector around the axis
|
||||
* @return the same vector
|
||||
*/
|
||||
@NotNull
|
||||
public Vector rotateAroundNonUnitAxis(@NotNull Vector axis, double angle) throws IllegalArgumentException {
|
||||
double x = getX(), y = getY(), z = getZ();
|
||||
double x2 = axis.getX(), y2 = axis.getY(), z2 = axis.getZ();
|
||||
|
||||
double cosTheta = Math.cos(angle);
|
||||
double sinTheta = Math.sin(angle);
|
||||
double dotProduct = this.dot(axis);
|
||||
|
||||
this.x = x2 * dotProduct * (1d - cosTheta)
|
||||
+ x * cosTheta
|
||||
+ (-z2 * y + y2 * z) * sinTheta;
|
||||
this.y = y2 * dotProduct * (1d - cosTheta)
|
||||
+ y * cosTheta
|
||||
+ (z2 * x - x2 * z) * sinTheta;
|
||||
this.z = z2 * dotProduct * (1d - cosTheta)
|
||||
+ z * cosTheta
|
||||
+ (-y2 * x + x2 * y) * sinTheta;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Vector)) {
|
||||
@ -278,27 +490,27 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
}
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(float x) {
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(float y) {
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public float getZ() {
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(float z) {
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
package net.minestom.server.utils.block;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import net.minestom.server.entity.LivingEntity;
|
||||
import net.minestom.server.instance.block.BlockFace;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
@ -10,6 +7,9 @@ import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* This class performs ray tracing and iterates along blocks on a line
|
||||
*/
|
||||
@ -48,9 +48,8 @@ public class BlockIterator implements Iterator<BlockPosition> {
|
||||
* @param maxDistance This is the maximum distance in blocks for the
|
||||
* trace. Setting this value above 140 may lead to problems with
|
||||
* unloaded chunks. A value of 0 indicates no limit
|
||||
*
|
||||
*/
|
||||
public BlockIterator(@NotNull Vector start, @NotNull Vector direction, float yOffset, int maxDistance) {
|
||||
public BlockIterator(@NotNull Vector start, @NotNull Vector direction, double yOffset, int maxDistance) {
|
||||
this.maxDistance = maxDistance;
|
||||
|
||||
Vector startClone = start.clone();
|
||||
@ -112,15 +111,15 @@ public class BlockIterator implements Iterator<BlockPosition> {
|
||||
// trace line backwards to find intercept with plane perpendicular to the main axis
|
||||
|
||||
double d = mainPosition / mainDirection; // how far to hit face behind
|
||||
double secondd = secondPosition - secondDirection * d;
|
||||
double thirdd = thirdPosition - thirdDirection * d;
|
||||
double second = secondPosition - secondDirection * d;
|
||||
double third = thirdPosition - thirdDirection * d;
|
||||
|
||||
// Guarantee that the ray will pass though the start block.
|
||||
// It is possible that it would miss due to rounding
|
||||
// This should only move the ray by 1 grid position
|
||||
secondError = floor(secondd * gridSize);
|
||||
secondError = floor(second * gridSize);
|
||||
secondStep = round(secondDirection / mainDirection * gridSize);
|
||||
thirdError = floor(thirdd * gridSize);
|
||||
thirdError = floor(third * gridSize);
|
||||
thirdStep = round(thirdDirection / mainDirection * gridSize);
|
||||
|
||||
if (secondError + secondStep <= 0) {
|
||||
@ -229,7 +228,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, float yOffset, int maxDistance) {
|
||||
public BlockIterator(@NotNull Position pos, double yOffset, int maxDistance) {
|
||||
this(pos.toVector(), pos.getDirection(), yOffset, maxDistance);
|
||||
}
|
||||
|
||||
@ -243,7 +242,7 @@ public class BlockIterator implements Iterator<BlockPosition> {
|
||||
* by this value
|
||||
*/
|
||||
|
||||
public BlockIterator(@NotNull Position pos, float yOffset) {
|
||||
public BlockIterator(@NotNull Position pos, double yOffset) {
|
||||
this(pos.toVector(), pos.getDirection(), yOffset, 0);
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ public final class ChunkUtils {
|
||||
* @param z instance Z coordinate
|
||||
* @return true if the chunk is loaded, false otherwise
|
||||
*/
|
||||
public static boolean isLoaded(@NotNull Instance instance, float x, float z) {
|
||||
public static boolean isLoaded(@NotNull Instance instance, double x, double z) {
|
||||
final int chunkX = getChunkCoordinate((int) x);
|
||||
final int chunkZ = getChunkCoordinate((int) z);
|
||||
|
||||
|
@ -270,12 +270,12 @@ public class EntityFinder {
|
||||
|
||||
if (targetSelector == TargetSelector.NEAREST_PLAYER) {
|
||||
Entity entity = null;
|
||||
float closestDistance = Float.MAX_VALUE;
|
||||
double closestDistance = Double.MAX_VALUE;
|
||||
|
||||
Collection<Player> instancePlayers = instance != null ?
|
||||
instance.getPlayers() : MinecraftServer.getConnectionManager().getOnlinePlayers();
|
||||
for (Player player : instancePlayers) {
|
||||
final float distance = player.getPosition().getDistance(startPosition);
|
||||
final double distance = player.getPosition().getDistance(startPosition);
|
||||
if (distance < closestDistance) {
|
||||
entity = player;
|
||||
closestDistance = distance;
|
||||
|
@ -23,9 +23,9 @@ public class RelativeVec extends RelativeLocation<Vector> {
|
||||
}
|
||||
final Position entityPosition = entity.getPosition();
|
||||
|
||||
final float x = location.getX() + (relativeX ? entityPosition.getX() : 0);
|
||||
final float y = location.getY() + (relativeY ? entityPosition.getY() : 0);
|
||||
final float z = location.getZ() + (relativeZ ? entityPosition.getZ() : 0);
|
||||
final double x = location.getX() + (relativeX ? entityPosition.getX() : 0);
|
||||
final double y = location.getY() + (relativeY ? entityPosition.getY() : 0);
|
||||
final double z = location.getZ() + (relativeZ ? entityPosition.getZ() : 0);
|
||||
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class PositionUtils {
|
||||
|
||||
public static void lookAlong(@NotNull Position position, float dx, float dy, float dz) {
|
||||
final float horizontalAngle = (float) Math.atan2(dz, dx);
|
||||
public static void lookAlong(@NotNull Position position, double dx, double dy, double dz) {
|
||||
final double horizontalAngle = Math.atan2(dz, dx);
|
||||
final float yaw = (float) (horizontalAngle * (180.0 / Math.PI)) - 90;
|
||||
final float pitch = (float) Math.atan2(dy, Math.max(Math.abs(dx), Math.abs(dz)));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user