Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 62 additions & 11 deletions Math/BlockPos.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using Newtonsoft.Json;
Expand Down Expand Up @@ -34,6 +35,21 @@ public int InternalY {
public int Y;
public int dimension;

public const int SlotDontCare = -1;

/// <summary>
/// Performs a very fast hashing function on the positional (X, Y, Z, and dimension) parameters. Guaranteed to avoid collisions
/// only when the change in any given coordinate is less than 16; do not use it for a cryptographic hash.
/// </summary>
public ushort FastHash => (ushort)((dimension << 12) + (Y << 8) + (X << 4) + Z);

[ProtoMember(4), DefaultValue(SlotDontCare)]
public int Slot {
get => (slot & 0xFFFF) == FastHash ? (slot >> 16) : SlotDontCare;
set => slot = (value << 16) | FastHash;
}
private int slot = SlotDontCare;

public const int DimensionBoundary = GlobalConstants.DimensionSizeInChunks * GlobalConstants.ChunkSize;


Expand Down Expand Up @@ -62,12 +78,14 @@ public BlockPos(int x, int y, int z)
this.dimension = y / DimensionBoundary;
}

public BlockPos(int x, int y, int z, int dim)
public BlockPos(int x, int y, int z, int dim) : this(x, y, z, dim, SlotDontCare) { }
public BlockPos(int x, int y, int z, int dim, int slot)
{
this.X = x;
this.Y = y;
this.Z = z;
this.dimension = dim;
this.Slot = slot;
}

[Obsolete("Not dimension-aware. Use overload with a dimension parameter instead")]
Expand All @@ -78,12 +96,14 @@ public BlockPos(Vec3i vec)
this.Z = vec.Z;
}

public BlockPos(Vec3i vec, int dim)
public BlockPos(Vec3i vec, int dim) : this(vec, dim, SlotDontCare) { }
public BlockPos(Vec3i vec, int dim, int slot)
{
this.X = vec.X;
this.Y = vec.Y;
this.Z = vec.Z;
this.dimension = dim;
this.Slot = slot;
}

/// <summary>
Expand All @@ -97,14 +117,14 @@ public BlockPos(Vec4i vec)
}

/// <summary>
/// 0 = x, 1 = y, 2 = z
/// 0 = x, 1 = y, 2 = z, 3 = dimension, 4 = slot
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public int this[int i]
{
get { return i == 0 ? X : i == 1 ? Y : i == 2 ? Z : dimension; }
set { if (i == 0) X = value; else if (i == 1) Y = value; else if (i == 2) Z = value; else dimension = value; }
get { return i == 0 ? X : i == 1 ? Y : i == 2 ? Z : i == 3 ? dimension : Slot; }
set { if (i == 0) X = value; else if (i == 1) Y = value; else if (i == 2) Z = value; else if (i == 3) dimension = value; else Slot = value; }
}

/// <summary>
Expand All @@ -115,6 +135,7 @@ public int this[int i]
public BlockPos Up(int dy = 1)
{
Y += dy;
Slot = SlotDontCare;
return this;
}

Expand All @@ -126,6 +147,7 @@ public BlockPos Up(int dy = 1)
public BlockPos Down(int dy = 1)
{
Y -= dy;
Slot = SlotDontCare;
return this;
}

Expand All @@ -139,6 +161,7 @@ public BlockPos Set(Vec3d origin)
X = (int)origin.X;
Y = (int)origin.Y;
Z = (int)origin.Z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -147,6 +170,7 @@ public BlockPos Set(Vec3i pos)
X = pos.X;
Y = pos.Y;
Z = pos.Z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -155,6 +179,7 @@ public BlockPos Set(FastVec3i pos)
X = pos.X;
Y = pos.Y;
Z = pos.Z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -169,6 +194,7 @@ public BlockPos SetAndCorrectDimension(Vec3d origin)
Y = (int)origin.Y % DimensionBoundary;
Z = (int)origin.Z;
dimension = (int)origin.Y / DimensionBoundary;
Slot = SlotDontCare;
return this;
}

Expand All @@ -185,6 +211,7 @@ public BlockPos SetAndCorrectDimension(int x, int y, int z)
Y = y % DimensionBoundary;
Z = z;
dimension = y / DimensionBoundary;
Slot = SlotDontCare;
return this;
}

Expand All @@ -202,6 +229,7 @@ public BlockPos Set(int x, int y, int z)
X = x;
Y = y;
Z = z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -210,6 +238,7 @@ public BlockPos Set(float x, float y, float z)
X = (int)x;
Y = (int)y;
Z = (int)z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -218,6 +247,7 @@ public BlockPos Set(BlockPos blockPos)
X = blockPos.X;
Y = blockPos.Y;
Z = blockPos.Z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -236,6 +266,12 @@ public BlockPos SetDimension(int dim)
return this;
}

public BlockPos SetSlot(int slot)
{
this.slot = slot;
return this;
}

/// <summary>
/// Sets this BlockPos to the x,y,z values given, and returns a boolean stating if the existing values were already equal to x,y,z
/// </summary>
Expand All @@ -249,9 +285,11 @@ public bool SetAndEquals(int x, int y, int z)
X = x;
Y = y;
Z = z;
Slot = SlotDontCare;
return false;
}

// this does not preserve slot, as it's only used for particles
public void ToBytes(BinaryWriter writer)
{
writer.Write(X);
Expand All @@ -273,6 +311,7 @@ public Vec3i ToLocalPosition(ICoreAPI api)
public BlockPos West()
{
X -= 1;
Slot = SlotDontCare;
return this;
}

Expand All @@ -284,18 +323,21 @@ public static BlockPos CreateFromBytes(BinaryReader reader)
public BlockPos North()
{
Z -= 1;
Slot = SlotDontCare;
return this;
}

public BlockPos East()
{
X += 1;
Slot = SlotDontCare;
return this;
}

public BlockPos South()
{
Z += 1;
Slot = SlotDontCare;
return this;
}

Expand Down Expand Up @@ -398,7 +440,7 @@ public BlockPos UpCopy(int length = 1)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual BlockPos Copy()
{
return new BlockPos(X, Y, Z, dimension);
return new BlockPos(X, Y, Z, dimension, Slot);
}


Expand All @@ -409,7 +451,7 @@ public virtual BlockPos Copy()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual BlockPos CopyAndCorrectDimension()
{
return new BlockPos(X, Y % DimensionBoundary, Z, dimension + Y / DimensionBoundary);
return new BlockPos(X, Y % DimensionBoundary, Z, dimension + Y / DimensionBoundary, Slot);
}


Expand All @@ -428,6 +470,7 @@ public BlockPos Add(float dx, float dy, float dz)
X += (int)dx;
Y += (int)dy;
Z += (int)dz;
Slot = SlotDontCare;
return this;
}

Expand All @@ -445,6 +488,7 @@ public BlockPos Add(int dx, int dy, int dz)
X += dx;
Y += dy;
Z += dz;
Slot = SlotDontCare;
return this;
}

Expand All @@ -459,6 +503,7 @@ public BlockPos Add(Vec3i vector)
X += vector.X;
Y += vector.Y;
Z += vector.Z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -473,6 +518,7 @@ public BlockPos Add(FastVec3i vector)
X += vector.X;
Y += vector.Y;
Z += vector.Z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -488,6 +534,7 @@ public BlockPos Add(BlockPos pos)
X += pos.X;
Y += pos.Y;
Z += pos.Z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -505,6 +552,7 @@ public BlockPos Add(BlockFacing facing, int length = 1)
X += faceNormals.X * length;
Y += faceNormals.Y * length;
Z += faceNormals.Z * length;
Slot = SlotDontCare;
return this;
}

Expand All @@ -520,6 +568,7 @@ public BlockPos Offset(BlockFacing facing)
X += faceNormals.X;
Y += faceNormals.Y;
Z += faceNormals.Z;
Slot = SlotDontCare;
return this;
}

Expand Down Expand Up @@ -606,6 +655,7 @@ public BlockPos Sub(BlockPos pos)
X -= pos.X;
Y -= pos.Y;
Z -= pos.Z;
Slot = SlotDontCare;
return this;
}

Expand All @@ -622,6 +672,7 @@ public BlockPos Sub(int x, int y, int z)
X -= x;
Y -= y;
Z -= z;
Slot = SlotDontCare;
return this;
}

Expand Down Expand Up @@ -814,22 +865,22 @@ public Vec3f ToVec3f()

public override string ToString()
{
return X + ", " + Y + ", " + Z + (dimension > 0 ? " : " + dimension : "");
return X + ", " + Y + ", " + Z + (Slot != SlotDontCare ? " / " + Slot : "") + (dimension > 0 ? " : " + dimension : "");
}

public override bool Equals(object obj)
{
return (obj is BlockPos pos) && X == pos.X && Y == pos.Y && Z == pos.Z && dimension == pos.dimension;
return (obj is BlockPos pos) && X == pos.X && Y == pos.Y && Z == pos.Z && dimension == pos.dimension && Slot == pos.Slot;
}

public override int GetHashCode()
{
return ((17 * 23 + X) * 23 + Y) * 23 + Z + dimension * 269023;
return ((17 * 23 + X) * 23 + Y) * 23 + Z + dimension * 269023 + Slot * 613849;
}

public bool Equals(BlockPos other)
{
return other != null && X == other.X && Y == other.Y && Z == other.Z && dimension == other.dimension;
return other != null && X == other.X && Y == other.Y && Z == other.Z && dimension == other.dimension && Slot == other.Slot;
}

public bool Equals(int x, int y, int z)
Expand Down