CnC_Remastered_Collection/CnCTDRAMapEditor/Model/CellMetrics.cs

138 lines
4.6 KiB
C#
Raw Normal View History

//
// Copyright 2020 Electronic Arts Inc.
//
// The Command & Conquer Map Editor and corresponding source code is free
// software: you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
// The Command & Conquer Map Editor and corresponding source code is distributed
// in the hope that it will be useful, but with permitted additional restrictions
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
// distributed with this program. You should have received a copy of the
// GNU General Public License along with permitted additional restrictions
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MobiusEditor.Model
{
public class CellMetrics
{
public static readonly FacingType[] AdjacentFacings = new FacingType[] {
FacingType.North, FacingType.NorthEast, FacingType.East, FacingType.SouthEast, FacingType.South, FacingType.SouthWest, FacingType.West, FacingType.NorthWest
};
public int Width { get; private set; }
public int Height { get; private set; }
public Point TopLeft => Point.Empty;
public Size Size => new Size(Width, Height);
public Rectangle Bounds => new Rectangle(TopLeft, Size);
public int Length => Width * Height;
public bool Contains(Point location) => ((location.X >= 0) && (location.X < Width) && (location.Y >= 0) && (location.Y < Height));
public bool Contains(int cell) => ((cell >= 0) && (cell < Length));
public CellMetrics(int width, int height)
{
Width = width;
Height = height;
}
public CellMetrics(Size size)
: this(size.Width, size.Height)
{
}
public bool GetCell(Point location, out int cell)
{
cell = (location.Y * Width) + location.X;
return Contains(location);
}
public bool GetLocation(int cell, out Point location)
{
location = new Point(cell % Width, cell / Width);
return Contains(cell);
}
public bool Adjacent(Point location, FacingType facing, out Point adjacent)
{
adjacent = location;
switch (facing)
{
case FacingType.North:
adjacent.Y--;
break;
case FacingType.NorthEast:
adjacent.X++;
adjacent.Y--;
break;
case FacingType.East:
adjacent.X++;
break;
case FacingType.SouthEast:
adjacent.X++;
adjacent.Y++;
break;
case FacingType.South:
adjacent.Y++;
break;
case FacingType.SouthWest:
adjacent.X--;
adjacent.Y++;
break;
case FacingType.West:
adjacent.X--;
break;
case FacingType.NorthWest:
adjacent.X--;
adjacent.Y--;
break;
}
return Contains(adjacent);
}
public bool Adjacent(int cell, FacingType facing, out int adjacent)
{
if (!GetLocation(cell, out Point location) || !Adjacent(location, facing, out Point adjacentPoint))
{
adjacent = -1;
return false;
}
else
{
return GetCell(adjacentPoint, out adjacent);
}
}
public void Clip(ref Point location)
{
location.X = Math.Max(0, Math.Min(Width - 1, location.X));
location.Y = Math.Max(0, Math.Min(Height - 1, location.Y));
}
public void Clip(ref Point location, Size margin)
{
Clip(ref location, margin, margin);
}
public void Clip(ref Point location, Size topLeftMargin, Size bottomRightMargin)
{
location.X = Math.Max(topLeftMargin.Width, Math.Min(Width - bottomRightMargin.Width - 1, location.X));
location.Y = Math.Max(topLeftMargin.Height, Math.Min(Height - bottomRightMargin.Height - 1, location.Y));
}
}
}