A game where you get to play as a slime, made with Godot.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
3.0 KiB

public struct Tile
{
public Corners<short> Height;
// TODO: Replace with enum or something more permanent?
public byte TexturePrimary;
public byte TextureSecondary;
public byte TextureBlend;
public readonly bool IsDefault
=> Height == default
&& TexturePrimary == 0
&& TextureSecondary == 0
&& TextureBlend == 0;
public readonly override string ToString()
=> $"Tile {{ Height = {Height}, TexturePrimary = {TexturePrimary}, TextureSecondary = {TextureSecondary}, TextureBlend = {TextureBlend} }}";
}
public readonly record struct TilePos(int X, int Z)
{
public Vector2 Center => new(X + 0.5f, Z + 0.5f);
public static TilePos operator +(TilePos left, Vector2I right) => new(left.X + right.X, left.Z + right.Y);
public static TilePos operator +(TilePos left, (int X, int Y) right) => new(left.X + right.X, left.Z + right.Y);
public static TilePos operator -(TilePos left, Vector2I right) => new(left.X - right.X, left.Z - right.Y);
public static TilePos operator -(TilePos left, (int X, int Y) right) => new(left.X - right.X, left.Z - right.Y);
public static explicit operator TilePos(Vector2I value) => new(value.X, value.Y);
public static explicit operator TilePos(Vector2 value) => new(FloorToInt(value.X), FloorToInt(value.Y));
public static explicit operator Vector2I(TilePos pos) => new(pos.X, pos.Z);
}
public struct Corners<T>(T topLeft, T topRight, T bottomRight, T bottomLeft)
: IEquatable<Corners<T>>
where T : IEquatable<T>
{
public T TopLeft = topLeft;
public T TopRight = topRight;
public T BottomRight = bottomRight;
public T BottomLeft = bottomLeft;
public Corners(T value)
: this(value, value, value, value) { }
public T this[Corner corner] {
readonly get => corner switch {
Corner.TopLeft => TopLeft,
Corner.TopRight => TopRight,
Corner.BottomRight => BottomRight,
Corner.BottomLeft => BottomLeft,
_ => throw new ArgumentException($"Invalid Corner value '{corner}'", nameof(corner)),
};
set { switch (corner) {
case Corner.TopLeft : TopLeft = value; break;
case Corner.TopRight : TopRight = value; break;
case Corner.BottomRight : BottomRight = value; break;
case Corner.BottomLeft : BottomLeft = value; break;
default: throw new ArgumentException($"Invalid Corner value '{corner}'", nameof(corner));
} }
}
public readonly bool Equals(Corners<T> other)
=> TopLeft .Equals(other.TopLeft )
&& TopRight .Equals(other.TopRight )
&& BottomRight.Equals(other.BottomRight)
&& BottomLeft .Equals(other.BottomLeft );
public readonly override bool Equals(object obj)
=> (obj is Corners<T> other) && Equals(other);
public readonly override int GetHashCode()
=> HashCode.Combine(TopLeft, TopRight, BottomRight, BottomLeft);
public readonly override string ToString()
=> $"Corners(TopLeft: {TopLeft}, TopRight: {TopRight}, BottomRight: {BottomRight}, BottomLeft: {BottomLeft})";
public static bool operator ==(Corners<T> left, Corners<T> right) => left.Equals(right);
public static bool operator !=(Corners<T> left, Corners<T> right) => !left.Equals(right);
}