mirror of
https://github.com/kwsch/NHSE.git
synced 2026-03-22 09:44:49 -05:00
Updates the Field Item Editor to render layers based on the entire map, and the per-patch positioning of each layer. Import/export will gracefully handle upgrade/downgrade, and viewport import/export will gracefully update tiles rather than a per-acre basis. Performance has also been slightly improved; no allocation is done anymore when updating the image.
129 lines
4.4 KiB
C#
129 lines
4.4 KiB
C#
namespace NHSE.Core;
|
|
|
|
public sealed class MapEditor
|
|
{
|
|
/// <summary>
|
|
/// Master interactor for mutating the map.
|
|
/// </summary>
|
|
public required MapMutator Mutator { get; init; }
|
|
|
|
/// <summary>
|
|
/// Amount of pixel upscaling compared to a 1px = 1 tile map.
|
|
/// </summary>
|
|
public int MapScale { get; set; } = 1;
|
|
|
|
/// <summary>
|
|
/// Amount of pixel upscaling compared to a 1px = 1 tile map.
|
|
/// </summary>
|
|
public int ViewScale { get; set; } = 16;
|
|
|
|
/// <summary>
|
|
/// Converts an upscaled coordinate to a tile coordinate.
|
|
/// </summary>
|
|
/// <param name="mX">X coordinate (mouse on upscaled image).</param>
|
|
/// <param name="mY">Y coordinate (mouse on upscaled image).</param>
|
|
public (int X, int Y) GetCursorCoordinates(in int mX, in int mY)
|
|
{
|
|
var x = mX / MapScale;
|
|
var y = mY / MapScale;
|
|
return (x, y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of the MapEditor class initialized from the specified save file.
|
|
/// </summary>
|
|
/// <param name="sav">The save file containing the data used to initialize the MapEditor. Cannot be null.</param>
|
|
/// <returns>A MapEditor instance populated with data from the provided save file.</returns>
|
|
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;
|
|
|
|
/// <summary>
|
|
/// Converts building map coordinates to view pixel coordinates.
|
|
/// </summary>
|
|
/// <param name="relX">Building map X coordinate.</param>
|
|
/// <param name="relY">Building map Y coordinate.</param>
|
|
/// <returns>View coordinates.</returns>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// From a map pixel coordinate (<see cref="MapScale"/>), get the clamped map tile coordinate.
|
|
/// </summary>
|
|
/// <param name="x">Upscaled Map pixel X coordinate.</param>
|
|
/// <param name="y">Upscaled Map pixel Y coordinate.</param>
|
|
/// <param name="type">Option to adjust the coordinates to a desired type.</param>
|
|
/// <returns></returns>
|
|
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
|
|
{
|
|
/// <summary>
|
|
/// No adjustment to the coordinates.
|
|
/// </summary>
|
|
None = 0,
|
|
|
|
/// <summary>
|
|
/// Snap the coordinates to the nearest acre boundary.
|
|
/// </summary>
|
|
SnapAcre,
|
|
|
|
/// <summary>
|
|
/// Center the view around the requested (x,y).
|
|
/// </summary>
|
|
Centered,
|
|
} |