mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 11:42:54 +08:00
Implement basic hold note + tick input.
This commit is contained in:
parent
d0e280dbef
commit
dcf879687d
@ -11,6 +11,9 @@ using OpenTK;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Mania.Timing;
|
||||
using osu.Framework.Configuration;
|
||||
using OpenTK.Input;
|
||||
using osu.Framework.Timing;
|
||||
|
||||
namespace osu.Desktop.VisualTests.Tests
|
||||
{
|
||||
@ -59,6 +62,48 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
}
|
||||
};
|
||||
|
||||
Action createPlayfieldWithNotesAcceptingInput = () =>
|
||||
{
|
||||
Clear();
|
||||
|
||||
var rateAdjustClock = new StopwatchClock(true) { Rate = 0.2 };
|
||||
|
||||
ManiaPlayfield playField;
|
||||
Add(playField = new ManiaPlayfield(4, new List<TimingChange> { new TimingChange { BeatLength = 200 } })
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(1, -1),
|
||||
Clock = new FramedClock(rateAdjustClock)
|
||||
});
|
||||
|
||||
playField.Add(new DrawableNote(new Note
|
||||
{
|
||||
StartTime = 1000,
|
||||
Column = 0
|
||||
}, new Bindable<Key>(Key.D)));
|
||||
|
||||
playField.Add(new DrawableHoldNote(new HoldNote
|
||||
{
|
||||
StartTime = 1000,
|
||||
Duration = 2000,
|
||||
Column = 1
|
||||
}, new Bindable<Key>(Key.F)));
|
||||
|
||||
playField.Add(new DrawableHoldNote(new HoldNote
|
||||
{
|
||||
StartTime = 1000,
|
||||
Duration = 2000,
|
||||
Column = 2
|
||||
}, new Bindable<Key>(Key.J)));
|
||||
|
||||
playField.Add(new DrawableNote(new Note
|
||||
{
|
||||
StartTime = 1000,
|
||||
Column = 3
|
||||
}, new Bindable<Key>(Key.K)));
|
||||
};
|
||||
|
||||
AddStep("1 column", () => createPlayfield(1, SpecialColumnPosition.Normal));
|
||||
AddStep("4 columns", () => createPlayfield(4, SpecialColumnPosition.Normal));
|
||||
AddStep("Left special style", () => createPlayfield(4, SpecialColumnPosition.Left));
|
||||
@ -76,6 +121,8 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
AddWaitStep(10);
|
||||
AddStep("Right special style", () => createPlayfieldWithNotes(4, SpecialColumnPosition.Right));
|
||||
AddWaitStep(10);
|
||||
|
||||
AddStep("Test", () => createPlayfieldWithNotesAcceptingInput());
|
||||
}
|
||||
|
||||
private void triggerKeyDown(Column column)
|
||||
|
@ -471,14 +471,17 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
}
|
||||
else
|
||||
{
|
||||
newObject = new HoldNote
|
||||
var holdNote = new HoldNote
|
||||
{
|
||||
StartTime = startTime,
|
||||
Samples = sampleInfoListAt(startTime),
|
||||
EndSamples = sampleInfoListAt(endTime),
|
||||
Column = column,
|
||||
Duration = endTime - startTime
|
||||
};
|
||||
|
||||
holdNote.HeadNote.Samples = sampleInfoListAt(startTime);
|
||||
holdNote.TailNote.Samples = sampleInfoListAt(endTime);
|
||||
|
||||
newObject = holdNote;
|
||||
}
|
||||
|
||||
pattern.Add(newObject);
|
||||
|
@ -69,18 +69,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
if (holdNote)
|
||||
{
|
||||
newObject = new HoldNote
|
||||
var hold = new HoldNote
|
||||
{
|
||||
StartTime = HitObject.StartTime,
|
||||
EndSamples = HitObject.Samples,
|
||||
Column = column,
|
||||
Duration = endTime - HitObject.StartTime
|
||||
};
|
||||
|
||||
newObject.Samples.Add(new SampleInfo
|
||||
hold.HeadNote.Samples.Add(new SampleInfo
|
||||
{
|
||||
Name = SampleInfo.HIT_NORMAL
|
||||
});
|
||||
|
||||
hold.TailNote.Samples = HitObject.Samples;
|
||||
|
||||
newObject = hold;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
13
osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs
Normal file
13
osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Judgements
|
||||
{
|
||||
public class HoldNoteTailJudgement : ManiaJudgement
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the hold note has been released too early and shouldn't give full score for the release.
|
||||
/// </summary>
|
||||
public bool HasBroken;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Judgements
|
||||
{
|
||||
public class HoldNoteTickJudgement : ManiaJudgement
|
||||
{
|
||||
}
|
||||
}
|
@ -7,14 +7,47 @@ using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Configuration;
|
||||
using OpenTK.Input;
|
||||
using osu.Framework.Input;
|
||||
using OpenTK;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
public class DrawableHoldNote : DrawableManiaHitObject<HoldNote>
|
||||
{
|
||||
private readonly NotePiece headPiece;
|
||||
private readonly DrawableNote headNote;
|
||||
private readonly DrawableNote tailNote;
|
||||
private readonly BodyPiece bodyPiece;
|
||||
private readonly NotePiece tailPiece;
|
||||
private readonly Container<DrawableHoldNoteTick> tickContainer;
|
||||
|
||||
/// <summary>
|
||||
/// Relative time at which the user started holding this note.
|
||||
/// </summary>
|
||||
private double holdStartTime;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the hold note has been released too early and shouldn't give full score for the release.
|
||||
/// </summary>
|
||||
private bool hasBroken;
|
||||
|
||||
private bool _holding;
|
||||
/// <summary>
|
||||
/// Whether the user is holding the hold note.
|
||||
/// </summary>
|
||||
private bool holding
|
||||
{
|
||||
get { return _holding; }
|
||||
set
|
||||
{
|
||||
if (_holding == value)
|
||||
return;
|
||||
_holding = value;
|
||||
|
||||
if (holding)
|
||||
holdStartTime = Time.Current;
|
||||
}
|
||||
}
|
||||
|
||||
public DrawableHoldNote(HoldNote hitObject, Bindable<Key> key = null)
|
||||
: base(hitObject, key)
|
||||
@ -32,17 +65,39 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
headPiece = new NotePiece
|
||||
tickContainer = new Container<DrawableHoldNoteTick>
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativeCoordinateSpace = new Vector2(1, (float)HitObject.Duration)
|
||||
},
|
||||
headNote = new DrawableHoldNoteHead(this, key)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre
|
||||
},
|
||||
tailPiece = new NotePiece
|
||||
tailNote = new DrawableHoldNoteTail(this, key)
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.TopCentre
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var tick in HitObject.Ticks)
|
||||
{
|
||||
var drawableTick = new DrawableHoldNoteTick(tick)
|
||||
{
|
||||
IsHolding = () => holding,
|
||||
HoldStartTime = () => holdStartTime
|
||||
};
|
||||
|
||||
drawableTick.Y -= (float)HitObject.StartTime;
|
||||
|
||||
tickContainer.Add(drawableTick);
|
||||
AddNested(drawableTick);
|
||||
}
|
||||
|
||||
AddNested(headNote);
|
||||
AddNested(tailNote);
|
||||
}
|
||||
|
||||
public override Color4 AccentColour
|
||||
@ -54,9 +109,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
return;
|
||||
base.AccentColour = value;
|
||||
|
||||
headPiece.AccentColour = value;
|
||||
bodyPiece.AccentColour = value;
|
||||
tailPiece.AccentColour = value;
|
||||
headNote.AccentColour = value;
|
||||
tailNote.AccentColour = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,14 +119,133 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
/// <summary>
|
||||
/// Handles key down events on the body of the hold note.
|
||||
/// </summary>
|
||||
/// <param name="state">The input state.</param>
|
||||
/// <param name="args">The key down args.</param>
|
||||
/// <returns>Whether the key press was handled.</returns>
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
{
|
||||
if (Time.Current > HitObject.StartTime)
|
||||
headPiece.Colour = Color4.Green;
|
||||
if (Time.Current > HitObject.EndTime)
|
||||
// Make sure the keypress happened within reasonable bounds of the hold note
|
||||
if (Time.Current < HitObject.StartTime || Time.Current > HitObject.EndTime)
|
||||
return false;
|
||||
|
||||
if (args.Key != Key)
|
||||
return false;
|
||||
|
||||
if (args.Repeat)
|
||||
return false;
|
||||
|
||||
holding = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles key up events on the body of the hold note.
|
||||
/// </summary>
|
||||
/// <param name="state">The input state.</param>
|
||||
/// <param name="args">The key down args.</param>
|
||||
/// <returns>Whether the key press was handled.</returns>
|
||||
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args)
|
||||
{
|
||||
// Make sure that the user started holding the key during the hold note
|
||||
if (!holding)
|
||||
return false;
|
||||
|
||||
if (args.Key != Key)
|
||||
return false;
|
||||
|
||||
holding = false;
|
||||
|
||||
// If the key has been released too early, they should not receive full score for the release
|
||||
if (!tailNote.Judged)
|
||||
hasBroken = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private class DrawableHoldNoteHead : DrawableNote
|
||||
{
|
||||
private readonly DrawableHoldNote holdNote;
|
||||
|
||||
public DrawableHoldNoteHead(DrawableHoldNote holdNote, Bindable<Key> key = null)
|
||||
: base(holdNote.HitObject.HeadNote, key)
|
||||
{
|
||||
bodyPiece.Colour = Color4.Green;
|
||||
tailPiece.Colour = Color4.Green;
|
||||
this.holdNote = holdNote;
|
||||
|
||||
RelativePositionAxes = Axes.None;
|
||||
Y = 0;
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
{
|
||||
if (!base.OnKeyDown(state, args))
|
||||
return false;
|
||||
|
||||
// We only want to trigger a holding state from the head if the head has received a judgement
|
||||
if (Judgement.Result == HitResult.None)
|
||||
return false;
|
||||
|
||||
// If the head has been missed, make sure the user also can't receive a full score for the release
|
||||
if (Judgement.Result == HitResult.Miss)
|
||||
holdNote.hasBroken = true;
|
||||
|
||||
holdNote.holding = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class DrawableHoldNoteTail : DrawableNote
|
||||
{
|
||||
private readonly DrawableHoldNote holdNote;
|
||||
|
||||
public DrawableHoldNoteTail(DrawableHoldNote holdNote, Bindable<Key> key = null)
|
||||
: base(holdNote.HitObject.TailNote, key)
|
||||
{
|
||||
this.holdNote = holdNote;
|
||||
|
||||
RelativePositionAxes = Axes.None;
|
||||
Y = 0;
|
||||
}
|
||||
|
||||
protected override ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement();
|
||||
|
||||
protected override void CheckJudgement(bool userTriggered)
|
||||
{
|
||||
base.CheckJudgement(userTriggered);
|
||||
|
||||
var tailJudgement = Judgement as HoldNoteTailJudgement;
|
||||
if (tailJudgement == null)
|
||||
return;
|
||||
|
||||
tailJudgement.HasBroken = holdNote.hasBroken;
|
||||
}
|
||||
|
||||
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args)
|
||||
{
|
||||
// Make sure that the user started holding the key during the hold note
|
||||
if (!holdNote.holding)
|
||||
return false;
|
||||
|
||||
if (Judgement.Result != HitResult.None)
|
||||
return false;
|
||||
|
||||
if (args.Key != Key)
|
||||
return false;
|
||||
|
||||
UpdateJudgement(true);
|
||||
|
||||
// Handled by the hold note, which will set holding = false
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
{
|
||||
// Tail doesn't handle key down
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Input;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
public class DrawableHoldNoteTick : DrawableManiaHitObject<HoldNoteTick>
|
||||
{
|
||||
public Func<double> HoldStartTime;
|
||||
public Func<bool> IsHolding;
|
||||
|
||||
public DrawableHoldNoteTick(HoldNoteTick hitObject)
|
||||
: base(hitObject, null)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override ManiaJudgement CreateJudgement() => new HoldNoteTickJudgement();
|
||||
|
||||
protected override void CheckJudgement(bool userTriggered)
|
||||
{
|
||||
if (!userTriggered)
|
||||
return;
|
||||
|
||||
if (Time.Current < HitObject.StartTime)
|
||||
return;
|
||||
|
||||
|
||||
if (HoldStartTime?.Invoke() > HitObject.StartTime)
|
||||
return;
|
||||
|
||||
Judgement.ManiaResult = ManiaHitResult.Perfect;
|
||||
Judgement.Result = HitResult.Hit;
|
||||
}
|
||||
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
switch (State)
|
||||
{
|
||||
case ArmedState.Hit:
|
||||
Colour = Color4.Green;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
if (Judgement.Result != HitResult.None)
|
||||
return;
|
||||
|
||||
if (IsHolding?.Invoke() != true)
|
||||
return;
|
||||
|
||||
UpdateJudgement(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Database;
|
||||
@ -12,32 +13,41 @@ namespace osu.Game.Rulesets.Mania.Objects
|
||||
/// <summary>
|
||||
/// Represents a hit object which requires pressing, holding, and releasing a key.
|
||||
/// </summary>
|
||||
public class HoldNote : Note, IHasEndTime
|
||||
public class HoldNote : ManiaHitObject, IHasEndTime
|
||||
{
|
||||
/// <summary>
|
||||
/// Lenience of release hit windows. This is to make cases where the hold note release
|
||||
/// is timed alongside presses of other hit objects less awkward.
|
||||
/// </summary>
|
||||
private const double release_window_lenience = 1.5;
|
||||
|
||||
public double Duration { get; set; }
|
||||
public double EndTime => StartTime + Duration;
|
||||
|
||||
/// <summary>
|
||||
/// The samples to be played when this hold note is released.
|
||||
/// </summary>
|
||||
public SampleInfoList EndSamples = new SampleInfoList();
|
||||
private Note headNote;
|
||||
public Note HeadNote => headNote ?? (headNote = new Note { StartTime = StartTime });
|
||||
|
||||
private Note tailNote;
|
||||
public Note TailNote => tailNote ?? (tailNote = new HoldNoteTail { StartTime = EndTime });
|
||||
|
||||
/// <summary>
|
||||
/// The key-release hit windows for this hold note.
|
||||
/// The length (in milliseconds) between ticks of this hold.
|
||||
/// </summary>
|
||||
public HitWindows ReleaseHitWindows { get; protected set; } = new HitWindows();
|
||||
private double tickSpacing = 50;
|
||||
|
||||
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
||||
public IEnumerable<HoldNoteTick> Ticks => ticks ?? (ticks = createTicks());
|
||||
private List<HoldNoteTick> ticks;
|
||||
|
||||
private List<HoldNoteTick> createTicks()
|
||||
{
|
||||
base.ApplyDefaults(controlPointInfo, difficulty);
|
||||
var ret = new List<HoldNoteTick>();
|
||||
|
||||
ReleaseHitWindows = HitWindows * release_window_lenience;
|
||||
if (tickSpacing == 0)
|
||||
return ret;
|
||||
|
||||
for (double t = StartTime + HeadNote.HitWindows.Great / 2; t <= EndTime - TailNote.HitWindows.Great / 2; t+= tickSpacing)
|
||||
{
|
||||
ret.Add(new HoldNoteTick
|
||||
{
|
||||
StartTime = t
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
osu.Game.Rulesets.Mania/Objects/HoldNoteTail.cs
Normal file
24
osu.Game.Rulesets.Mania/Objects/HoldNoteTail.cs
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects
|
||||
{
|
||||
public class HoldNoteTail : Note
|
||||
{
|
||||
/// <summary>
|
||||
/// Lenience of release hit windows. This is to make cases where the hold note release
|
||||
/// is timed alongside presses of other hit objects less awkward.
|
||||
/// </summary>
|
||||
private const double release_window_lenience = 1.5;
|
||||
|
||||
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
||||
{
|
||||
base.ApplyDefaults(controlPointInfo, difficulty);
|
||||
|
||||
HitWindows *= release_window_lenience;
|
||||
}
|
||||
}
|
||||
}
|
9
osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs
Normal file
9
osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects
|
||||
{
|
||||
public class HoldNoteTick : ManiaHitObject
|
||||
{
|
||||
}
|
||||
}
|
@ -57,10 +57,13 @@
|
||||
<Compile Include="Beatmaps\Patterns\Pattern.cs" />
|
||||
<Compile Include="MathUtils\FastRandom.cs" />
|
||||
<Compile Include="Judgements\HitWindows.cs" />
|
||||
<Compile Include="Judgements\HoldNoteTailJudgement.cs" />
|
||||
<Compile Include="Judgements\HoldNoteTickJudgement.cs" />
|
||||
<Compile Include="Judgements\ManiaHitResult.cs" />
|
||||
<Compile Include="Judgements\ManiaJudgement.cs" />
|
||||
<Compile Include="ManiaDifficultyCalculator.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableHoldNote.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableHoldNoteTick.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableManiaHitObject.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableNote.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\BodyPiece.cs" />
|
||||
@ -68,6 +71,8 @@
|
||||
<Compile Include="Objects\Types\IHasColumn.cs" />
|
||||
<Compile Include="Scoring\ManiaScoreProcessor.cs" />
|
||||
<Compile Include="Objects\HoldNote.cs" />
|
||||
<Compile Include="Objects\HoldNoteTail.cs" />
|
||||
<Compile Include="Objects\HoldNoteTick.cs" />
|
||||
<Compile Include="Objects\ManiaHitObject.cs" />
|
||||
<Compile Include="Objects\Note.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user