package net.CyanWool.api.world; import net.CyanWool.api.block.Block; import net.CyanWool.api.utils.NumberConversions; import net.CyanWool.api.utils.Vector; public class Location implements Cloneable { private World world; private double x; private double y; private double z; private float pitch; private float yaw; public Location(World world, double x, double y, double z) { this(world, x, y, z, 0, 0); } public Location(World world, double x, double y, double z, float pitch) { this(world, x, y, z, pitch, 0); } public Location(World world, double x, double y, double z, float pitch, float yaw) { this.world = world; this.x = x; this.y = y; this.z = z; this.pitch = pitch; this.yaw = yaw; } public int getBlockX() { return NumberConversions.floor(x); // TODO } public int getBlockY() { return NumberConversions.floor(y); // TODO } public int getBlockZ() { return NumberConversions.floor(z); // TODO } public World getWorld() { return world; } public Block getBlock() { return world.getBlock(this);// TODO } public Chunk getChunk() { return world.getChunkManager().getChunkFromBlockCoords(getBlockX(), getBlockZ()); } 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 getPitch() { return pitch; } public void setPitch(float pitch) { this.pitch = pitch; } public float getYaw() { return yaw; } public void setYaw(float yaw) { this.yaw = yaw; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Location other = (Location) obj; if (this.world != other.world && (this.world == null || !this.world.equals(other.world))) { 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 Location clone() { try { return (Location) super.clone(); } catch (CloneNotSupportedException e) { throw new Error(e); } } public double distance(Location o) { return Math.sqrt(distanceSquared(o)); } 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); } 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; } 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; } 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; } public Location add(Vector vec) { this.x += vec.getX(); this.y += vec.getY(); this.z += vec.getZ(); return this; } public Location add(double x, double y, double z) { this.x += x; this.y += y; this.z += z; return this; } 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; } public Location subtract(Vector vec) { this.x -= vec.getX(); this.y -= vec.getY(); this.z -= vec.getZ(); return this; } public Location subtract(double x, double y, double z) { this.x -= x; this.y -= y; this.z -= z; return this; } }