138 lines
4.6 KiB
C#
138 lines
4.6 KiB
C#
|
//
|
|||
|
// 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));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|