Template
mirror of
https://github.com/LOOHP/Limbo.git
synced 2026-10-22 12:38:55 +00:00
reupload
This commit is contained in:
@@ -0,0 +1,468 @@
|
||||
package com.loohp.limbo.location;
|
||||
|
||||
import com.loohp.limbo.Limbo;
|
||||
import com.loohp.limbo.utils.NumberConversions;
|
||||
import com.loohp.limbo.world.BlockState;
|
||||
import com.loohp.limbo.world.World;
|
||||
|
||||
public class Location implements Cloneable {
|
||||
|
||||
private World world;
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private float yaw;
|
||||
private float pitch;
|
||||
|
||||
public Location(World world, double x, double y, double z, float yaw, float pitch) {
|
||||
this.world = world;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public Location(World world, double x, double y, double z) {
|
||||
this(world, x, y, z, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location clone() {
|
||||
try {
|
||||
return (Location) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public BlockState getBlockState() {
|
||||
return world.getBlock((int) x,(int) y,(int) z);
|
||||
}
|
||||
|
||||
public void setBlockState(BlockState state) {
|
||||
world.setBlock((int) x, (int) y, (int) z, state);
|
||||
}
|
||||
|
||||
public boolean isWorldLoaded() {
|
||||
return Limbo.getInstance().getWorld(world.getName()) != null;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public void setWorld(World world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
public void setYaw(float yaw) {
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public void setPitch(float pitch) {
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a unit-vector pointing in the direction that this Location is
|
||||
* facing.
|
||||
*
|
||||
* @return a vector pointing the direction of this location's {@link
|
||||
* #getPitch() pitch} and {@link #getYaw() yaw}
|
||||
*/
|
||||
public Vector getDirection() {
|
||||
Vector vector = new Vector();
|
||||
|
||||
double rotX = this.getYaw();
|
||||
double rotY = this.getPitch();
|
||||
|
||||
vector.setY(-Math.sin(Math.toRadians(rotY)));
|
||||
|
||||
double xz = Math.cos(Math.toRadians(rotY));
|
||||
|
||||
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
|
||||
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link #getYaw() yaw} and {@link #getPitch() pitch} to point
|
||||
* in the direction of the vector.
|
||||
*
|
||||
* @param vector the direction vector
|
||||
* @return the same location
|
||||
*/
|
||||
public Location setDirection(Vector vector) {
|
||||
/*
|
||||
* Sin = Opp / Hyp
|
||||
* Cos = Adj / Hyp
|
||||
* Tan = Opp / Adj
|
||||
*
|
||||
* x = -Opp
|
||||
* z = Adj
|
||||
*/
|
||||
final double _2PI = 2 * Math.PI;
|
||||
final double x = vector.getX();
|
||||
final double z = vector.getZ();
|
||||
|
||||
if (x == 0 && z == 0) {
|
||||
pitch = vector.getY() > 0 ? -90 : 90;
|
||||
return this;
|
||||
}
|
||||
|
||||
double theta = Math.atan2(-x, z);
|
||||
yaw = (float) Math.toDegrees((theta + _2PI) % _2PI);
|
||||
|
||||
double x2 = NumberConversions.square(x);
|
||||
double z2 = NumberConversions.square(z);
|
||||
double xz = Math.sqrt(x2 + z2);
|
||||
pitch = (float) Math.toDegrees(Math.atan(-vector.getY() / xz));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the location by another.
|
||||
*
|
||||
* @see Vector
|
||||
* @param vec The other location
|
||||
* @return the same location
|
||||
* @throws IllegalArgumentException for differing worlds
|
||||
*/
|
||||
public Location add(Location vec) {
|
||||
if (vec == null || vec.getWorld() != getWorld()) {
|
||||
throw new IllegalArgumentException("Cannot add Locations of differing worlds");
|
||||
}
|
||||
|
||||
x += vec.x;
|
||||
y += vec.y;
|
||||
z += vec.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the location by a vector.
|
||||
*
|
||||
* @see Vector
|
||||
* @param vec Vector to use
|
||||
* @return the same location
|
||||
*/
|
||||
public Location add(Vector vec) {
|
||||
this.x += vec.getX();
|
||||
this.y += vec.getY();
|
||||
this.z += vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the location by another. Not world-aware.
|
||||
*
|
||||
* @see Vector
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @return the same location
|
||||
*/
|
||||
public Location add(double x, double y, double z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the location by another.
|
||||
*
|
||||
* @see Vector
|
||||
* @param vec The other location
|
||||
* @return the same location
|
||||
* @throws IllegalArgumentException for differing worlds
|
||||
*/
|
||||
public Location subtract(Location vec) {
|
||||
if (vec == null || vec.getWorld() != getWorld()) {
|
||||
throw new IllegalArgumentException("Cannot add Locations of differing worlds");
|
||||
}
|
||||
|
||||
x -= vec.x;
|
||||
y -= vec.y;
|
||||
z -= vec.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the location by a vector.
|
||||
*
|
||||
* @see Vector
|
||||
* @param vec The vector to use
|
||||
* @return the same location
|
||||
*/
|
||||
public Location subtract(Vector vec) {
|
||||
this.x -= vec.getX();
|
||||
this.y -= vec.getY();
|
||||
this.z -= vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the location by another. Not world-aware and
|
||||
* orientation independent.
|
||||
*
|
||||
* @see Vector
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @return the same location
|
||||
*/
|
||||
public Location subtract(double x, double y, double z) {
|
||||
this.x -= x;
|
||||
this.y -= y;
|
||||
this.z -= z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the magnitude of the location, defined as sqrt(x^2+y^2+z^2). The
|
||||
* value of this method is not cached and uses a costly square-root
|
||||
* function, so do not repeatedly call this method to get the location's
|
||||
* magnitude. NaN will be returned if the inner result of the sqrt()
|
||||
* function overflows, which will be caused if the length is too long. Not
|
||||
* world-aware and orientation independent.
|
||||
*
|
||||
* @return the magnitude
|
||||
* @see Vector
|
||||
*/
|
||||
public double length() {
|
||||
return Math.sqrt(NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the magnitude of the location squared. Not world-aware and
|
||||
* orientation independent.
|
||||
*
|
||||
* @return the magnitude
|
||||
* @see Vector
|
||||
*/
|
||||
public double lengthSquared() {
|
||||
return NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the distance between this location and another. The value of this
|
||||
* method is not cached and uses a costly square-root function, so do not
|
||||
* repeatedly call this method to get the location's magnitude. NaN will
|
||||
* be returned if the inner result of the sqrt() function overflows, which
|
||||
* will be caused if the distance is too long.
|
||||
*
|
||||
* @param o The other location
|
||||
* @return the distance
|
||||
* @throws IllegalArgumentException for differing worlds
|
||||
* @see Vector
|
||||
*/
|
||||
public double distance(Location o) {
|
||||
return Math.sqrt(distanceSquared(o));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the squared distance between this location and another.
|
||||
*
|
||||
* @param o The other location
|
||||
* @return the distance
|
||||
* @throws IllegalArgumentException for differing worlds
|
||||
* @see Vector
|
||||
*/
|
||||
public double distanceSquared(Location o) {
|
||||
if (o == null) {
|
||||
throw new IllegalArgumentException("Cannot measure distance to a null location");
|
||||
} else if (o.getWorld() == null || getWorld() == null) {
|
||||
throw new IllegalArgumentException("Cannot measure distance to a null world");
|
||||
} else if (o.getWorld() != getWorld()) {
|
||||
throw new IllegalArgumentException("Cannot measure distance between " + getWorld().getName() + " and " + o.getWorld().getName());
|
||||
}
|
||||
|
||||
return NumberConversions.square(x - o.x) + NumberConversions.square(y - o.y) + NumberConversions.square(z - o.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs scalar multiplication, multiplying all components with a
|
||||
* scalar. Not world-aware.
|
||||
*
|
||||
* @param m The factor
|
||||
* @return the same location
|
||||
* @see Vector
|
||||
*/
|
||||
public Location multiply(double m) {
|
||||
x *= m;
|
||||
y *= m;
|
||||
z *= m;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero this location's components. Not world-aware.
|
||||
*
|
||||
* @return the same location
|
||||
* @see Vector
|
||||
*/
|
||||
public Location zero() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Vector} based on this Location
|
||||
*
|
||||
* @return New Vector containing the coordinates represented by this
|
||||
* Location
|
||||
*/
|
||||
public Vector toVector() {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if each component of this Location is finite.
|
||||
*
|
||||
* @throws IllegalArgumentException if any component is not finite
|
||||
*/
|
||||
public void checkFinite() throws IllegalArgumentException {
|
||||
NumberConversions.checkFinite(x, "x not finite");
|
||||
NumberConversions.checkFinite(y, "y not finite");
|
||||
NumberConversions.checkFinite(z, "z not finite");
|
||||
NumberConversions.checkFinite(pitch, "pitch not finite");
|
||||
NumberConversions.checkFinite(yaw, "yaw not finite");
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely converts a double (location coordinate) to an int (block
|
||||
* coordinate)
|
||||
*
|
||||
* @param loc Precise coordinate
|
||||
* @return Block coordinate
|
||||
*/
|
||||
public static int locToBlock(double loc) {
|
||||
return NumberConversions.floor(loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the given yaw angle to a value between <code>+/-180</code>
|
||||
* degrees.
|
||||
*
|
||||
* @param yaw the yaw in degrees
|
||||
* @return the normalized yaw in degrees
|
||||
* @see Location#getYaw()
|
||||
*/
|
||||
public static float normalizeYaw(float yaw) {
|
||||
yaw %= 360.0f;
|
||||
if (yaw >= 180.0f) {
|
||||
yaw -= 360.0f;
|
||||
} else if (yaw < -180.0f) {
|
||||
yaw += 360.0f;
|
||||
}
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the given pitch angle to a value between <code>+/-90</code>
|
||||
* degrees.
|
||||
*
|
||||
* @param pitch the pitch in degrees
|
||||
* @return the normalized pitch in degrees
|
||||
* @see Location#getPitch()
|
||||
*/
|
||||
public static float normalizePitch(float pitch) {
|
||||
if (pitch > 90.0f) {
|
||||
pitch = 90.0f;
|
||||
} else if (pitch < -90.0f) {
|
||||
pitch = -90.0f;
|
||||
}
|
||||
return pitch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Location{" + "world=" + world + ",x=" + x + ",y=" + y + ",z=" + z + ",pitch=" + pitch + ",yaw=" + yaw + "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Location other = (Location) obj;
|
||||
|
||||
World world = (this.world == null) ? null : this.world;
|
||||
World otherWorld = (other.world == null) ? null : other.world;
|
||||
if (world != otherWorld && (world == null || !world.equals(otherWorld))) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(this.x) != Double.doubleToLongBits(other.x)) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(this.y) != Double.doubleToLongBits(other.y)) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(this.z) != Double.doubleToLongBits(other.z)) {
|
||||
return false;
|
||||
}
|
||||
if (Float.floatToIntBits(this.pitch) != Float.floatToIntBits(other.pitch)) {
|
||||
return false;
|
||||
}
|
||||
if (Float.floatToIntBits(this.yaw) != Float.floatToIntBits(other.yaw)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
|
||||
World world = (this.world == null) ? null : this.world;
|
||||
hash = 19 * hash + (world != null ? world.hashCode() : 0);
|
||||
hash = 19 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32));
|
||||
hash = 19 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32));
|
||||
hash = 19 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32));
|
||||
hash = 19 * hash + Float.floatToIntBits(this.pitch);
|
||||
hash = 19 * hash + Float.floatToIntBits(this.yaw);
|
||||
return hash;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user