namespace NHSE.Core; public sealed class MapEditor { /// /// Master interactor for mutating the map. /// public required MapMutator Mutator { get; init; } /// /// Amount of pixel upscaling compared to a 1px = 1 tile map. /// public int MapScale { get; set; } = 1; /// /// Amount of pixel upscaling compared to a 1px = 1 tile map. /// public int ViewScale { get; set; } = 16; /// /// Converts an upscaled coordinate to a tile coordinate. /// /// X coordinate (mouse on upscaled image). /// Y coordinate (mouse on upscaled image). public (int X, int Y) GetCursorCoordinates(in int mX, in int mY) { var x = mX / MapScale; var y = mY / MapScale; return (x, y); } /// /// Creates a new instance of the MapEditor class initialized from the specified save file. /// /// The save file containing the data used to initialize the MapEditor. Cannot be null. /// A MapEditor instance populated with data from the provided save file. public static MapEditor FromSaveFile(MainSave sav) => new() { Mutator = MapMutator.FromSaveFile(sav) }; public int X => Mutator.View.X; public int Y => Mutator.View.Y; public LayerTerrain Terrain => Mutator.Manager.LayerTerrain; public ILayerBuilding Buildings => Mutator.Manager.LayerBuildings; public ILayerFieldItemSet Items => Mutator.Manager.FieldItems; /// /// Converts building map coordinates to view pixel coordinates. /// /// Building map X coordinate. /// Building map Y coordinate. /// View coordinates. public (int X, int Y) GetViewCoordinatesBuilding(uint relX, uint relY) => GetViewCoordinates((int)relX, (int)relY, Mutator.Manager.ConfigBuildings); public (int X, int Y) GetViewCoordinatesTerrain(int relX, int relY) => GetViewCoordinates(relX, relY, Mutator.Manager.ConfigTerrain); public (int X, int Y) GetViewCoordinatesFieldItem(int relX, int relY) => GetViewCoordinates(relX, relY, Mutator.Manager.ConfigItems); public (int X, int Y) GetViewCoordinates(int posX, int posY, LayerPositionConfig shifter) { // Get absolute coordinates from the layer. var (x, y) = shifter.GetCoordinatesAbsolute(posX, posY); // Shift to view coordinates x -= X; y -= Y; // Scale to pixel coordinates x *= ViewScale; y *= ViewScale; return (x, y); } /// /// From a map pixel coordinate (), get the clamped map tile coordinate. /// /// Upscaled Map pixel X coordinate. /// Upscaled Map pixel Y coordinate. /// Option to adjust the coordinates to a desired type. /// public (int X, int Y) GetMapCoordinates(int x, int y, MapViewCoordinateRequest type) { x /= MapScale; y /= MapScale; if (x < 0) x = 0; if (y < 0) y = 0; // Adjust the view coordinate if (type == MapViewCoordinateRequest.Centered) { // Reticle size is GridWidth, center = /2 var shift = (LayerFieldItem.TilesPerAcreDim * MapScale) / 2; x -= shift; y -= shift; } else if (type == MapViewCoordinateRequest.SnapAcre) { // Snap to the nearest acre x -= x % LayerFieldItem.TilesPerAcreDim; y -= y % LayerFieldItem.TilesPerAcreDim; } var view = Mutator.View; // Clamp to viewport dimensions, and center to nearest acre if desired. // Clamp to boundaries so that we always have a full grid to view. return view.EnforceEdgeBuffer(x, y); } } public enum MapViewCoordinateRequest { /// /// No adjustment to the coordinates. /// None = 0, /// /// Snap the coordinates to the nearest acre boundary. /// SnapAcre, /// /// Center the view around the requested (x,y). /// Centered, }