parent
464c0f3f1c
commit
8ad77c4616
4 changed files with 245 additions and 238 deletions
@ -0,0 +1,29 @@ |
||||
public static class SideAndCornerExtensions |
||||
{ |
||||
public static (Corner, Corner) GetCorners(this Side side) |
||||
=> side switch { |
||||
Side.Left => (Corner.TopLeft, Corner.BottomLeft), |
||||
Side.Top => (Corner.TopLeft, Corner.TopRight), |
||||
Side.Right => (Corner.TopRight, Corner.BottomRight), |
||||
Side.Bottom => (Corner.BottomLeft, Corner.BottomRight), |
||||
_ => throw new ArgumentException($"Invalid Side value '{side}'", nameof(side)), |
||||
}; |
||||
|
||||
public static Side GetOpposite(this Side side) |
||||
=> side switch { |
||||
Side.Left => Side.Right, |
||||
Side.Top => Side.Bottom, |
||||
Side.Right => Side.Left, |
||||
Side.Bottom => Side.Top, |
||||
_ => throw new ArgumentException($"Invalid Side value '{side}'", nameof(side)), |
||||
}; |
||||
|
||||
public static Corner GetOpposite(this Corner corner) |
||||
=> corner switch { |
||||
Corner.TopLeft => Corner.BottomRight, |
||||
Corner.TopRight => Corner.BottomLeft, |
||||
Corner.BottomRight => Corner.TopLeft, |
||||
Corner.BottomLeft => Corner.TopRight, |
||||
_ => throw new ArgumentException($"Invalid Corner value '{corner}'", nameof(corner)), |
||||
}; |
||||
} |
@ -0,0 +1,129 @@ |
||||
using Dictionary = Godot.Collections.Dictionary; |
||||
|
||||
public readonly record struct TilePos(int X, int Y) |
||||
{ |
||||
public TilePos GetNeighbor(Side side) |
||||
=> side switch { |
||||
Side.Left => new(X - 1, Y), |
||||
Side.Top => new(X, Y - 1), |
||||
Side.Right => new(X + 1, Y), |
||||
Side.Bottom => new(X, Y + 1), |
||||
_ => throw new ArgumentException($"Invalid Side value '{side}'", nameof(side)), |
||||
}; |
||||
|
||||
public TilePos GetNeighbor(Corner corner) |
||||
=> corner switch { |
||||
Corner.TopLeft => new(X - 1, Y - 1), |
||||
Corner.TopRight => new(X + 1, Y - 1), |
||||
Corner.BottomRight => new(X + 1, Y + 1), |
||||
Corner.BottomLeft => new(X - 1, Y + 1), |
||||
_ => throw new ArgumentException($"Invalid Corner value '{corner}'", nameof(corner)), |
||||
}; |
||||
|
||||
public static TilePos From(Vector2I value) => new(value.X, value.Y); |
||||
public Vector2I ToVector2I() => new(X, Y); |
||||
} |
||||
|
||||
public struct Tile |
||||
{ |
||||
public Corners<float> Height; |
||||
|
||||
// TODO: Replace with enum or something more permanent? |
||||
public int TexturePrimary; |
||||
public int TextureSecondary; |
||||
public int TextureBlend; |
||||
|
||||
|
||||
public static Tile FromDictionary(Dictionary dict) |
||||
{ |
||||
if (dict == null) return default; |
||||
|
||||
float topLeft, topRight, bottomRight, bottomLeft; |
||||
switch (dict["heights"]) { |
||||
case { VariantType: Variant.Type.Float } variant: |
||||
var height = (float)variant; |
||||
(topLeft, topRight, bottomRight, bottomLeft) = (height, height, height, height); |
||||
break; |
||||
case { VariantType: Variant.Type.PackedFloat32Array } variant: |
||||
var heights = (float[])variant; |
||||
(topLeft, topRight, bottomRight, bottomLeft) = (heights[0], heights[1], heights[2], heights[3]); |
||||
break; |
||||
default: throw new Exception("Invalid variant type"); |
||||
}; |
||||
|
||||
int texturePrimary, textureSecondary, textureBlend; |
||||
switch (dict["texture"]) { |
||||
case { VariantType: Variant.Type.Int } variant: |
||||
var texture = (int)variant; |
||||
(texturePrimary, textureSecondary, textureBlend) = (texture, 0, 0); |
||||
break; |
||||
case { VariantType: Variant.Type.PackedInt32Array } variant: |
||||
var textures = (int[])variant; |
||||
(texturePrimary, textureSecondary, textureBlend) = (textures[0], textures[1], textures[2]); |
||||
break; |
||||
default: throw new Exception("Invalid variant type"); |
||||
}; |
||||
|
||||
return new(){ |
||||
Height = new(topLeft, topRight, bottomRight, bottomLeft), |
||||
TexturePrimary = texturePrimary, |
||||
TextureSecondary = textureSecondary, |
||||
TextureBlend = textureBlend, |
||||
}; |
||||
} |
||||
|
||||
public readonly Dictionary ToDictionary() |
||||
{ |
||||
if (Height.IsZeroApprox() && (TexturePrimary == 0) && (TextureBlend == 0)) |
||||
return null; |
||||
return new(){ |
||||
["heights"] = Height.IsEqualApprox() ? Height.TopLeft : new[]{ Height.TopLeft, Height.TopRight, Height.BottomRight, Height.BottomLeft }, |
||||
["texture"] = (TextureBlend == 0) ? TexturePrimary : new[]{ TexturePrimary, TextureSecondary, TextureBlend }, |
||||
}; |
||||
} |
||||
} |
||||
|
||||
public struct Corners<T>(T topLeft, T topRight, T bottomRight, T bottomLeft) |
||||
{ |
||||
public T TopLeft = topLeft; |
||||
public T TopRight = topRight; |
||||
public T BottomRight = bottomRight; |
||||
public T BottomLeft = bottomLeft; |
||||
|
||||
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 static class CornersExtensions |
||||
{ |
||||
public static void Adjust(this ref Corners<float> self, float amount) |
||||
{ |
||||
self.TopLeft += amount; |
||||
self.TopRight += amount; |
||||
self.BottomRight += amount; |
||||
self.BottomLeft += amount; |
||||
} |
||||
|
||||
public static bool IsZeroApprox(this Corners<float> self) |
||||
=> Mathf.IsZeroApprox(self.TopLeft ) && Mathf.IsZeroApprox(self.TopRight ) |
||||
&& Mathf.IsZeroApprox(self.BottomRight) && Mathf.IsZeroApprox(self.BottomLeft); |
||||
|
||||
public static bool IsEqualApprox(this Corners<float> self) |
||||
=> Mathf.IsEqualApprox(self.TopLeft, self.TopRight ) |
||||
&& Mathf.IsEqualApprox(self.TopLeft, self.BottomRight) |
||||
&& Mathf.IsEqualApprox(self.TopLeft, self.BottomLeft ); |
||||
} |
Loading…
Reference in new issue