-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expand file tree
/
Copy pathManiaPlayfield.cs
More file actions
167 lines (133 loc) · 5.58 KB
/
ManiaPlayfield.cs
File metadata and controls
167 lines (133 loc) · 5.58 KB
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Primitives;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
using osuTK;
namespace osu.Game.Rulesets.Mania.UI
{
[Cached]
public partial class ManiaPlayfield : ScrollingPlayfield
{
public IReadOnlyList<Stage> Stages => stages;
private readonly List<Stage> stages = new List<Stage>();
public override Quad SkinnableComponentScreenSpaceDrawQuad
{
get
{
RectangleF totalArea = RectangleF.Empty;
for (int i = 0; i < Stages.Count; ++i)
{
var stageArea = Stages[i].ScreenSpaceDrawQuad.AABBFloat;
totalArea = i == 0 ? stageArea : RectangleF.Union(totalArea, stageArea);
}
return totalArea;
}
}
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos)
{
foreach (var s in stages)
{
if (s.ReceivePositionalInputAt(screenSpacePos))
return true;
}
return false;
}
public ManiaPlayfield(List<StageDefinition> stageDefinitions)
{
ArgumentNullException.ThrowIfNull(stageDefinitions);
if (stageDefinitions.Count <= 0)
throw new ArgumentException("Can't have zero or fewer stages.");
GridContainer playfieldGrid;
AddInternal(playfieldGrid = new GridContainer
{
RelativeSizeAxes = Axes.Both,
Content = new[] { new Drawable[stageDefinitions.Count] }
});
var columnAction = ManiaAction.Key1;
int firstColumnIndex = 0;
for (int i = 0; i < stageDefinitions.Count; i++)
{
var newStage = CreateStage(firstColumnIndex, stageDefinitions[i], ref columnAction);
playfieldGrid.Content[0][i] = newStage;
stages.Add(newStage);
AddNested(newStage);
firstColumnIndex += newStage.Columns.Length;
}
}
[Pure]
protected virtual Stage CreateStage(int firstColumnIndex, StageDefinition stageDefinition, ref ManiaAction columnAction) => new Stage(firstColumnIndex, stageDefinition, ref columnAction);
public override void Add(HitObject hitObject) => getStageByColumn(((ManiaHitObject)hitObject).Column).Add(hitObject);
public override bool Remove(HitObject hitObject) => getStageByColumn(((ManiaHitObject)hitObject).Column).Remove(hitObject);
public override void Add(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Add(h);
public override bool Remove(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Remove(h);
public void Add(BarLine barLine) => stages.ForEach(s => s.Add(barLine));
/// <summary>
/// Find the closest column to the proposed screen space position.
/// </summary>
/// <param name="screenSpaceX">The screen-space X coordinate.</param>
/// <returns>The column which the <paramref name="screenSpaceX"/> is closest to.</returns>
public Column GetClosestColumnByPosition(float screenSpaceX)
{
return stages
.SelectMany(s => s.Columns.Select((Column column, float distance) (c) => (c, Math.Abs(screenSpaceX - c.ScreenSpaceDrawQuad.Centre.X))))
.MinBy(c => c.distance).column;
}
/// <summary>
/// Retrieves a <see cref="Column"/> by index.
/// </summary>
/// <param name="index">The index of the column.</param>
/// <returns>The <see cref="Column"/> corresponding to the given index.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is less than 0 or greater than <see cref="TotalColumns"/>.</exception>
public Column GetColumn(int index)
{
if (index < 0 || index > TotalColumns - 1)
throw new ArgumentOutOfRangeException(nameof(index));
foreach (var stage in stages)
{
if (index >= stage.Columns.Length)
{
index -= stage.Columns.Length;
continue;
}
return stage.Columns[index];
}
throw new ArgumentOutOfRangeException(nameof(index));
}
/// <summary>
/// Retrieves the total amount of columns across all stages in this playfield.
/// </summary>
public int TotalColumns
{
get
{
int sum = 0;
foreach (var stage in stages)
sum += stage.Columns.Length;
return sum;
}
}
private Stage getStageByColumn(int column)
{
int sum = 0;
foreach (var stage in stages)
{
sum += stage.Columns.Length;
if (sum > column)
return stage;
}
return null;
}
}
}