using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MinecraftClient.Mapping { /// /// Represents a location into a Minecraft world /// public struct Location { /// /// The X Coordinate /// public double X; /// /// The Y Coordinate (vertical) /// public double Y; /// /// The Z coordinate /// public double Z; /// /// Get location with zeroed coordinates /// public static Location Zero { get { return new Location(0, 0, 0); } } /// /// Create a new location /// public Location(double x, double y, double z) { X = x; Y = y; Z = z; } /// /// Create a new location /// /// Location of the chunk into the world /// Location of the chunk into the world /// Location of the block into the chunk /// Location of the block into the world /// Location of the block into the chunk public Location(int chunkX, int chunkZ, int blockX, int blockY, int blockZ) { X = chunkX * Chunk.SizeX + blockX; Y = blockY; Z = chunkZ * Chunk.SizeZ + blockZ; } /// /// The X index of the corresponding chunk in the world /// public int ChunkX { get { return (int)Math.Floor(X / Chunk.SizeX); } } /// /// The Y index of the corresponding chunk in the world /// public int ChunkY { get { return (int)Math.Floor(Y / Chunk.SizeY); } } /// /// The Z index of the corresponding chunk in the world /// public int ChunkZ { get { return (int)Math.Floor(Z / Chunk.SizeZ); } } /// /// The X index of the corresponding block in the corresponding chunk of the world /// public int ChunkBlockX { get { return ((int)Math.Floor(X) % Chunk.SizeX + Chunk.SizeX) % Chunk.SizeX; } } /// /// The Y index of the corresponding block in the corresponding chunk of the world /// public int ChunkBlockY { get { return ((int)Math.Floor(Y) % Chunk.SizeY + Chunk.SizeY) % Chunk.SizeY; } } /// /// The Z index of the corresponding block in the corresponding chunk of the world /// public int ChunkBlockZ { get { return ((int)Math.Floor(Z) % Chunk.SizeZ + Chunk.SizeZ) % Chunk.SizeZ; } } /// /// Get a squared distance to the specified location /// /// Other location for computing distance /// Distance to the specified location, without using a square root public double DistanceSquared(Location location) { return ((X - location.X) * (X - location.X)) + ((Y - location.Y) * (Y - location.Y)) + ((Z - location.Z) * (Z - location.Z)); } /// /// Get exact distance to the specified location /// /// Other location for computing distance /// Distance to the specified location, with square root so lower performances public double Distance(Location location) { return Math.Sqrt(DistanceSquared(location)); } /// /// Considering the current location as Feet location, calculate Eyes location /// /// Player Eyes location public Location EyesLocation() { return this + new Location(0, 1.62, 0); } /// /// Compare two locations. Locations are equals if the integer part of their coordinates are equals. /// /// Object to compare to /// TRUE if the locations are equals public override bool Equals(object obj) { if (obj == null) return false; if (obj is Location) { return ((int)this.X) == ((int)((Location)obj).X) && ((int)this.Y) == ((int)((Location)obj).Y) && ((int)this.Z) == ((int)((Location)obj).Z); } return false; } /// /// Compare two locations. Locations are equals if the integer part of their coordinates are equals. /// /// First location to compare /// Second location to compare /// TRUE if the locations are equals public static bool operator ==(Location loc1, Location loc2) { if (loc1 == null && loc2 == null) return true; if (loc1 == null || loc2 == null) return false; return loc1.Equals(loc2); } /// /// Compare two locations. Locations are not equals if the integer part of their coordinates are not equals. /// /// First location to compare /// Second location to compare /// TRUE if the locations are equals public static bool operator !=(Location loc1, Location loc2) { if (loc1 == null && loc2 == null) return false; if (loc1 == null || loc2 == null) return true; return !loc1.Equals(loc2); } /// /// Sums two locations and returns the result. /// /// /// Thrown if one of the provided location is null /// /// First location to sum /// Second location to sum /// Sum of the two locations public static Location operator +(Location loc1, Location loc2) { return new Location ( loc1.X + loc2.X, loc1.Y + loc2.Y, loc1.Z + loc2.Z ); } /// /// Substract a location to another /// /// /// Thrown if one of the provided location is null /// /// First location /// Location to substract to the first one /// Sum of the two locations public static Location operator -(Location loc1, Location loc2) { return new Location ( loc1.X - loc2.X, loc1.Y - loc2.Y, loc1.Z - loc2.Z ); } /// /// Multiply a location by a scalar value /// /// Location to multiply /// Scalar value /// Product of the location and the scalar value public static Location operator *(Location loc, double val) { return new Location ( loc.X * val, loc.Y * val, loc.Z * val ); } /// /// Divide a location by a scalar value /// /// Location to divide /// Scalar value /// Result of the division public static Location operator /(Location loc, double val) { return new Location ( loc.X / val, loc.Y / val, loc.Z / val ); } /// /// DO NOT USE. Defined to comply with C# requirements requiring a GetHashCode() when overriding Equals() or == /// /// /// A modulo will be applied if the location is outside the following ranges: /// X: -4096 to +4095 /// Y: -32 to +31 /// Z: -4096 to +4095 /// /// A simplified version of the location public override int GetHashCode() { return (((int)X) & ~((~0) << 13)) << 19 | (((int)Y) & ~((~0) << 13)) << 13 | (((int)Z) & ~((~0) << 06)) << 00; } /// /// Convert the location into a string representation /// /// String representation of the location public override string ToString() { return String.Format("X:{0} Y:{1} Z:{2}", X, Y, Z); } } }