-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
Copy pathHoldNote.cs
140 lines (114 loc) · 4.21 KB
/
HoldNote.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
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
// 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 System.Collections.Generic;
using System.Threading;
using osu.Game.Audio;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Mania.Objects
{
/// <summary>
/// Represents a hit object which requires pressing, holding, and releasing a key.
/// </summary>
public class HoldNote : ManiaHitObject, IHasDuration
{
public double EndTime
{
get => StartTime + Duration;
set => Duration = value - StartTime;
}
private double duration;
public double Duration
{
get => duration;
set
{
duration = value;
if (Tail != null)
Tail.StartTime = EndTime;
}
}
public override double StartTime
{
get => base.StartTime;
set
{
base.StartTime = value;
if (Head != null)
Head.StartTime = value;
if (Tail != null)
Tail.StartTime = EndTime;
}
}
public override int Column
{
get => base.Column;
set
{
base.Column = value;
if (Head != null)
Head.Column = value;
if (Tail != null)
Tail.Column = value;
}
}
public IList<IList<HitSampleInfo>> NodeSamples { get; set; }
/// <summary>
/// The head note of the hold.
/// </summary>
public HeadNote Head { get; protected set; }
/// <summary>
/// The tail note of the hold.
/// </summary>
public TailNote Tail { get; protected set; }
/// <summary>
/// The body of the hold.
/// This is an invisible and silent object that tracks the holding state of the <see cref="HoldNote"/>.
/// </summary>
public HoldNoteBody Body { get; protected set; }
public override double MaximumJudgementOffset => Tail.MaximumJudgementOffset;
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
base.CreateNestedHitObjects(cancellationToken);
// Generally node samples will be populated by ManiaBeatmapConverter, but in a case like the editor they may not be.
// Ensure they are set to a sane default here.
NodeSamples ??= CreateDefaultNodeSamples(this);
AddNested(Head = new HeadNote
{
StartTime = StartTime,
Column = Column,
Samples = GetNodeSamples(0),
});
AddNested(Tail = new TailNote
{
StartTime = EndTime,
Column = Column,
Samples = GetNodeSamples(NodeSamples.Count - 1),
});
AddNested(Body = new HoldNoteBody
{
StartTime = StartTime,
Column = Column
});
}
public override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
public IList<HitSampleInfo> GetNodeSamples(int nodeIndex) => nodeIndex < NodeSamples?.Count ? NodeSamples[nodeIndex] : Samples;
/// <summary>
/// Create the default note samples for a hold note, based off their main sample.
/// </summary>
/// <remarks>
/// By default, osu!mania beatmaps in only play samples at the start of the hold note.
/// </remarks>
/// <param name="obj">The object to use as a basis for the head sample.</param>
/// <returns>Defaults for assigning to <see cref="HoldNote.NodeSamples"/>.</returns>
public static List<IList<HitSampleInfo>> CreateDefaultNodeSamples(HitObject obj) => new List<IList<HitSampleInfo>>
{
obj.Samples,
new List<HitSampleInfo>(),
};
}
}