using System; namespace NHSE.Core { /// /// Basic logic implementation for interacting with the manipulatable tile grid. /// /// /// Certain use this as a viewport on a subsection of the entire tile-set. /// public abstract class TileGrid { /// Amount of viewable tiles wide public readonly int GridWidth; /// Amount of viewable tiles high public readonly int GridHeight; /// Max amount of tiles wide the entire grid is public readonly int MaxWidth; /// Max amount of tiles high the entire grid is public readonly int MaxHeight; protected TileGrid(in int gw, in int gh, in int mw, in int mh) { GridWidth = gw; GridHeight = gh; MaxWidth = mw; MaxHeight = mh; } /// /// Amount of tiles present in the grid. /// public int GridTileCount => GridWidth * GridHeight; /// /// Amount of ALL tiles present in the entire grid (including the grid). /// public int MaxTileCount => MaxWidth * MaxHeight; protected int GetTileIndex(in int x, in int y) => (MaxHeight * x) + y; public void ClampCoordinatesInsideGrid(ref int x, ref int y) => ClampCoordinatesTo(ref x, ref y, MaxWidth - 1, MaxHeight - 1); public void ClampCoordinatesTopLeft(ref int x, ref int y) { int maxX = MaxWidth - GridWidth; int maxY = MaxHeight - GridHeight; ClampCoordinatesTo(ref x, ref y, maxX, maxY); } private static void ClampCoordinatesTo(ref int x, ref int y, int maxX, int maxY) { x = Math.Max(0, Math.Min(x, maxX)); y = Math.Max(0, Math.Min(y, maxY)); } public void GetViewAnchorCoordinates(ref int x, ref int y, in bool centerReticle) { // If we aren't snapping the reticle to the nearest acre // we want to put the middle of the reticle rectangle where the cursor is. // Adjust the view coordinate if (!centerReticle) { // Reticle size is GridWidth, center = /2 x -= GridWidth / 2; y -= GridWidth / 2; } // Clamp to viewport dimensions, and center to nearest acre if desired. // Clamp to boundaries so that we always have 16x16 to view. ClampCoordinatesTopLeft(ref x, ref y); } } }