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,
}