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