/
DoorFinder.cs
80 lines (72 loc) · 3.43 KB
/
DoorFinder.cs
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
72
73
74
75
76
77
78
79
80
using System.Collections.Generic;
using GoRogue.MapGeneration.ContextComponents;
using JetBrains.Annotations;
using SadRogue.Primitives;
using SadRogue.Primitives.GridViews;
namespace GoRogue.MapGeneration.Steps
{
/// <summary>
/// Finds the locations of open walls in rectangular rooms that constitute doorways.
/// </summary>
[PublicAPI]
public class DoorFinder : GenerationStep
{
/// <summary>
/// Optional tag that must be associated with the grid view used to find openings in room walls.
/// </summary>
public readonly string? WallFloorComponentTag;
/// <summary>
/// Optional tag that must be associated with the component used to store rectangular rooms that it generates
/// door locations for.
/// </summary>
public readonly string? RoomsComponentTag;
/// <summary>
/// Optional tag that must be associated with the component created/used to record the door locations found by
/// this algorithm.
/// </summary>
public readonly string? DoorsListComponentTag;
/// <summary>
/// Creates a door finder generation step.
/// </summary>
/// <param name="name">The name of the generation step. Defaults to <see cref="DoorFinder"/></param>
/// <param name="wallFloorComponentTag">
/// Optional tag that must be associated with the grid view used to find whether room walls are open.
/// Defaults to "WallFloor".
/// </param>
/// <param name="roomsComponentTag">
/// Optional tag that must be associated with the component used to store the rectangular rooms this algorithm
/// finds openings for. Defaults to "Rooms".
/// </param>
/// <param name="doorsListComponentTag">
/// Optional tag that must be associated with the component created/used to record the door locations found
/// by this algorithm. Defaults to "Doors".
/// </param>
public DoorFinder(string? name = null, string? wallFloorComponentTag = "WallFloor",
string? roomsComponentTag = "Rooms", string? doorsListComponentTag = "Doors")
: base(name,
(typeof(IGridView<bool>), wallFloorComponentTag),
(typeof(ItemList<Rectangle>), roomsComponentTag))
{
WallFloorComponentTag = wallFloorComponentTag;
RoomsComponentTag = roomsComponentTag;
DoorsListComponentTag = doorsListComponentTag;
}
/// <inheritdoc/>
protected override IEnumerator<object?> OnPerform(GenerationContext context)
{
// Get required components; guaranteed to exist because enforced by required components list
var wallFloor = context.GetFirst<IGridView<bool>>(WallFloorComponentTag);
var roomsList = context.GetFirst<ItemList<Rectangle>>(RoomsComponentTag);
// Get/create doors component
var doorsList = context.GetFirstOrNew(() => new DoorList(), DoorsListComponentTag);
// Go through each room and add door locations for it
foreach (var room in roomsList.Items)
{
foreach (var perimeterPos in room.Expand(1, 1).PerimeterPositions())
if (wallFloor[perimeterPos])
doorsList.AddDoor(Name, room, perimeterPos);
yield return null;
}
}
}
}