CellMetrics.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // The Command & Conquer Map Editor and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // The Command & Conquer Map Editor and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Drawing;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. namespace MobiusEditor.Model
  21. {
  22. public class CellMetrics
  23. {
  24. public static readonly FacingType[] AdjacentFacings = new FacingType[] {
  25. FacingType.North, FacingType.NorthEast, FacingType.East, FacingType.SouthEast, FacingType.South, FacingType.SouthWest, FacingType.West, FacingType.NorthWest
  26. };
  27. public int Width { get; private set; }
  28. public int Height { get; private set; }
  29. public Point TopLeft => Point.Empty;
  30. public Size Size => new Size(Width, Height);
  31. public Rectangle Bounds => new Rectangle(TopLeft, Size);
  32. public int Length => Width * Height;
  33. public bool Contains(Point location) => ((location.X >= 0) && (location.X < Width) && (location.Y >= 0) && (location.Y < Height));
  34. public bool Contains(int cell) => ((cell >= 0) && (cell < Length));
  35. public CellMetrics(int width, int height)
  36. {
  37. Width = width;
  38. Height = height;
  39. }
  40. public CellMetrics(Size size)
  41. : this(size.Width, size.Height)
  42. {
  43. }
  44. public bool GetCell(Point location, out int cell)
  45. {
  46. cell = (location.Y * Width) + location.X;
  47. return Contains(location);
  48. }
  49. public bool GetLocation(int cell, out Point location)
  50. {
  51. location = new Point(cell % Width, cell / Width);
  52. return Contains(cell);
  53. }
  54. public bool Adjacent(Point location, FacingType facing, out Point adjacent)
  55. {
  56. adjacent = location;
  57. switch (facing)
  58. {
  59. case FacingType.North:
  60. adjacent.Y--;
  61. break;
  62. case FacingType.NorthEast:
  63. adjacent.X++;
  64. adjacent.Y--;
  65. break;
  66. case FacingType.East:
  67. adjacent.X++;
  68. break;
  69. case FacingType.SouthEast:
  70. adjacent.X++;
  71. adjacent.Y++;
  72. break;
  73. case FacingType.South:
  74. adjacent.Y++;
  75. break;
  76. case FacingType.SouthWest:
  77. adjacent.X--;
  78. adjacent.Y++;
  79. break;
  80. case FacingType.West:
  81. adjacent.X--;
  82. break;
  83. case FacingType.NorthWest:
  84. adjacent.X--;
  85. adjacent.Y--;
  86. break;
  87. }
  88. return Contains(adjacent);
  89. }
  90. public bool Adjacent(int cell, FacingType facing, out int adjacent)
  91. {
  92. if (!GetLocation(cell, out Point location) || !Adjacent(location, facing, out Point adjacentPoint))
  93. {
  94. adjacent = -1;
  95. return false;
  96. }
  97. else
  98. {
  99. return GetCell(adjacentPoint, out adjacent);
  100. }
  101. }
  102. public void Clip(ref Point location)
  103. {
  104. location.X = Math.Max(0, Math.Min(Width - 1, location.X));
  105. location.Y = Math.Max(0, Math.Min(Height - 1, location.Y));
  106. }
  107. public void Clip(ref Point location, Size margin)
  108. {
  109. Clip(ref location, margin, margin);
  110. }
  111. public void Clip(ref Point location, Size topLeftMargin, Size bottomRightMargin)
  112. {
  113. location.X = Math.Max(topLeftMargin.Width, Math.Min(Width - bottomRightMargin.Width - 1, location.X));
  114. location.Y = Math.Max(topLeftMargin.Height, Math.Min(Height - bottomRightMargin.Height - 1, location.Y));
  115. }
  116. }
  117. }