rokojori_action_library/Runtime/Math/Hexagon/HexagonCoord.cs

181 lines
3.8 KiB
C#
Raw Normal View History

2026-10-04 20:14:14 +00:00
using Godot;
using System.Collections.Generic;
namespace Rokojori;
public struct HexagonCoord
{
public readonly int q;
public readonly int r;
public HexagonCoord( int q, int r )
{
this.q = q;
this.r = r;
}
public readonly static HexagonCoord Center = new HexagonCoord( 0, 0 );
public HexagonCoord Middle => Center;
public readonly static HexagonCoord East = new HexagonCoord( 1, 0 );
public HexagonCoord Left => East;
public readonly static HexagonCoord NorthEast = new HexagonCoord( 1, -1 );
public HexagonCoord LeftUp => NorthEast;
public readonly static HexagonCoord NorthWest = new HexagonCoord( 0, -1 );
public HexagonCoord RightUp => NorthWest;
public readonly static HexagonCoord West = new HexagonCoord( -1, 0 );
public HexagonCoord Right => West;
public readonly static HexagonCoord SouthWest = new HexagonCoord( -1, 1 );
public HexagonCoord RightDown => SouthWest;
public readonly static HexagonCoord SouthEast = new HexagonCoord( 0, 1 );
public HexagonCoord LeftDown => SouthEast;
static readonly HexagonCoord[] directions = new HexagonCoord[]
{
new HexagonCoord( 1, 0 ),
new HexagonCoord( 1, -1 ),
new HexagonCoord( 0, -1 ),
new HexagonCoord( -1, 0 ),
new HexagonCoord( -1, 1 ),
new HexagonCoord( 0, 1 )
};
public static HexagonCoord Direction( int direction )
{
2026-10-04 20:39:10 +00:00
RJLog.Log( direction );
2026-10-04 20:14:14 +00:00
return directions[ direction ];
}
public HexagonCoord Neighbor( int direction )
{
var d = directions[ direction ];
return this + directions[ direction ];
}
2026-10-04 20:39:10 +00:00
public void ForEachNeighbor( System.Action<HexagonCoord> callback )
{
for ( int i = 0; i < directions.Length; i++ )
{
callback( Neighbor( i ) );
}
}
2026-10-04 20:14:14 +00:00
public Vector3 ToWorldPosition( float size )
{
var x = size * 1.5f * q;
var z = size * ( Mathf.Sqrt( 3f ) * 0.5f * q + Mathf.Sqrt( 3f ) * r );
return new Vector3( x, 0, z );
}
public static HexagonCoord operator +(HexagonCoord a, HexagonCoord b)
{
return new HexagonCoord(
a.q + b.q,
a.r + b.r
);
}
public static HexagonCoord operator -(HexagonCoord a, HexagonCoord b)
{
return new HexagonCoord(
a.q - b.q,
a.r - b.r
);
}
public static HexagonCoord operator -(HexagonCoord a)
{
return new HexagonCoord(
-a.q,
-a.r
);
}
public static HexagonCoord operator *(HexagonCoord a, int scalar)
{
return new HexagonCoord(
a.q * scalar,
a.r * scalar
);
}
public static HexagonCoord operator *(int scalar, HexagonCoord a)
{
return a * scalar;
}
public static HexagonCoord operator /(HexagonCoord a, int scalar)
{
return new HexagonCoord(
a.q / scalar,
a.r / scalar
);
}
public static bool operator ==(HexagonCoord a, HexagonCoord b)
{
return a.q == b.q && a.r == b.r;
}
public static bool operator !=(HexagonCoord a, HexagonCoord b)
{
return !(a == b);
}
public override bool Equals( object obj )
{
return obj is HexagonCoord other && other.q == q && other.r == r;
}
public override int GetHashCode()
{
return q * 397 ^ r;
}
public static List<HexagonCoord> Ring( int radius )
{
return Ring( HexagonCoord.Center, radius );
}
2026-10-04 20:39:10 +00:00
2026-10-04 20:14:14 +00:00
public static List<HexagonCoord> Ring( HexagonCoord center, int radius )
{
var results = new List<HexagonCoord>();
if ( radius == 0 )
{
results.Add( center );
return results;
}
var hex = center;
for ( int i = 0; i < radius; i++ )
{
hex = hex.Neighbor( 4 );
}
for ( int side = 0; side < 6; side++ )
{
for ( int step = 0; step < radius; step++ )
{
results.Add( hex );
hex = hex.Neighbor( side );
}
}
return results;
}
}