diff options
Diffstat (limited to 'scripts/Map/MapDivision.cs')
| -rw-r--r-- | scripts/Map/MapDivision.cs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/scripts/Map/MapDivision.cs b/scripts/Map/MapDivision.cs new file mode 100644 index 0000000..e50b331 --- /dev/null +++ b/scripts/Map/MapDivision.cs @@ -0,0 +1,113 @@ +using Godot; + +namespace TheLegendOfGustav.Map; + +/// <summary> +/// Classe utilizada pelo gerador de mapas. +/// Uma divisão é uma região retangular de espaço que pode +/// conter dentro de si duas regiões menores *ou* uma sala. +/// Uma divisão é uma árvore binária que possui espaço para salas em suas folhas. +/// </summary> +public partial class MapDivision : RefCounted +{ + public MapDivision(Vector2I position, Vector2I size) + { + Position = position; + Size = size; + } + + public MapDivision(Vector2I position, int width, int height) + { + Position = position; + Size = new(width, height); + } + + public MapDivision(int x, int y, int width, int height) + { + Position = new(x, y); + Size = new(width, height); + } + + /// <summary> + /// Região retangular da divisão. + /// </summary> + public Vector2I Position { get; set; } + public Vector2I Size { get; set; } + + public Vector2I Center + { + get => new(Position.X + Size.X / 2, Position.Y + Size.Y / 2); + } + + /// <summary> + /// Filhos da árvore + /// </summary> + public MapDivision Left { get; private set; } + public MapDivision Right { get; private set; } + + /// <summary> + /// Se a divisão atual for uma folha. + /// As folhas representam salas. + /// </summary> + public bool IsLeaf + { + get => Left == null && Right == null; + } + + /// <summary> + /// É conveniente ter acesso à todas as folhas da árvore. + /// </summary> + /// <returns>Lista com todas as folhas da árvore.</returns> + public Godot.Collections.Array<MapDivision> GetLeaves() + { + if (IsLeaf) + { + Godot.Collections.Array<MapDivision> list = []; + list.Add(this); + return list; + } + return Left.GetLeaves() + Right.GetLeaves(); + } + + /// <summary> + /// Algoritmo para gerar as divisões. + /// O mapa começa com uma única divisão que oculpa sua extensão completa. + /// Depois disso, ela se dividirá recursivamente n vezes. + /// As divisões nas folhas representam espaços onde pode gerar uma sala. + /// </summary> + /// <param name="iterations">Número de iterações</param> + /// <param name="rng">Gerador de números</param> + public void Split(int iterations, RandomNumberGenerator rng) + { + float SplitRatio = rng.RandfRange(0.35f, 0.65f); + bool horizontalSplit = Size.X <= Size.Y; + + // Eu defini um limite mínimo de 4 de altura e 4 de largura para divisões. + + if (horizontalSplit) + { + int leftHeight = (int)(Size.Y * SplitRatio); + if (leftHeight > 4 && Size.Y - leftHeight > 4) + { + Left = new MapDivision(Position, Size.X, leftHeight); + Right = new MapDivision(Position.X, Position.Y + leftHeight, Size.X, Size.Y - leftHeight); + } + } + else + { + int leftWidth = (int)(Size.Y * SplitRatio); + + if (leftWidth > 4 && Size.Y - leftWidth > 4) + { + Left = new MapDivision(Position, leftWidth, Size.Y); + Right = new MapDivision(Position.X + leftWidth, Position.Y, Size.X - leftWidth, Size.Y); + } + } + + if (iterations > 1) + { + Left?.Split(iterations - 1, rng); + Right?.Split(iterations - 1, rng); + } + } +}
\ No newline at end of file |
