summaryrefslogtreecommitdiff
path: root/scripts/map/MapDivision.cs
blob: 15a6be8577f95e9c1d807a1467d8cebda4b8e0a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System.Linq;
using System.Numerics;
using System.Xml.Schema;
using Godot;

public partial class MapDivision : RefCounted {
	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);
	}

	private MapDivision left;
	public MapDivision Left { get => this.left; }
	private MapDivision right;
	public MapDivision Right { get => this.right; }

	public bool IsLeaf {
		get => left == null && right == null;
	}

	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);
	}

	public Godot.Collections.Array<MapDivision> GetLeaves() {
		if (IsLeaf) {
			Godot.Collections.Array<MapDivision> list = [];
			list.Add(this);
			return list;
		}
		return left.GetLeaves() + right.GetLeaves();
	}

	public void Split(int iterations, RandomNumberGenerator rng) {
		float SplitRatio = rng.RandfRange(0.35f, 0.65f);
		bool horizontalSplit = Size.X <= Size.Y;

		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);
		}
	}
}