mirror of
https://github.com/osukey/osukey.git
synced 2025-08-08 00:53:56 +09:00
Merge pull request #9146 from peppy/taiko-editor
Implement osu!taiko editor
This commit is contained in:
17
osu.Game.Rulesets.Taiko.Tests/TestSceneEditor.cs
Normal file
17
osu.Game.Rulesets.Taiko.Tests/TestSceneEditor.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneEditor : EditorTestScene
|
||||||
|
{
|
||||||
|
public TestSceneEditor()
|
||||||
|
: base(new TaikoRuleset())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Taiko.Edit;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
using osu.Game.Screens.Edit;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Tests
|
||||||
|
{
|
||||||
|
public class TestSceneTaikoHitObjectComposer : EditorClockTestScene
|
||||||
|
{
|
||||||
|
[SetUp]
|
||||||
|
public void Setup() => Schedule(() =>
|
||||||
|
{
|
||||||
|
BeatDivisor.Value = 8;
|
||||||
|
Clock.Seek(0);
|
||||||
|
|
||||||
|
Child = new TestComposer { RelativeSizeAxes = Axes.Both };
|
||||||
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void BasicTest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestComposer : CompositeDrawable
|
||||||
|
{
|
||||||
|
[Cached(typeof(EditorBeatmap))]
|
||||||
|
[Cached(typeof(IBeatSnapProvider))]
|
||||||
|
public readonly EditorBeatmap EditorBeatmap;
|
||||||
|
|
||||||
|
public TestComposer()
|
||||||
|
{
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
EditorBeatmap = new EditorBeatmap(new TaikoBeatmap())
|
||||||
|
{
|
||||||
|
BeatmapInfo = { Ruleset = new TaikoRuleset().RulesetInfo }
|
||||||
|
},
|
||||||
|
new TaikoHitObjectComposer(new TaikoRuleset())
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
EditorBeatmap.Add(new Hit { StartTime = 125 * i });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class DrumRollPlacementBlueprint : TaikoSpanPlacementBlueprint
|
||||||
|
{
|
||||||
|
public DrumRollPlacementBlueprint()
|
||||||
|
: base(new DrumRoll())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPiece.cs
Normal file
35
osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPiece.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class HitPiece : CompositeDrawable
|
||||||
|
{
|
||||||
|
public HitPiece()
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
InternalChild = new CircularContainer
|
||||||
|
{
|
||||||
|
Masking = true,
|
||||||
|
BorderThickness = 10,
|
||||||
|
BorderColour = Color4.Yellow,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
AlwaysPresent = true,
|
||||||
|
Alpha = 0,
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class HitPlacementBlueprint : PlacementBlueprint
|
||||||
|
{
|
||||||
|
private readonly HitPiece piece;
|
||||||
|
|
||||||
|
private static Hit hit;
|
||||||
|
|
||||||
|
public HitPlacementBlueprint()
|
||||||
|
: base(hit = new Hit())
|
||||||
|
{
|
||||||
|
InternalChild = piece = new HitPiece
|
||||||
|
{
|
||||||
|
Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
|
{
|
||||||
|
switch (e.Button)
|
||||||
|
{
|
||||||
|
case MouseButton.Left:
|
||||||
|
hit.Type = HitType.Centre;
|
||||||
|
EndPlacement(true);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case MouseButton.Right:
|
||||||
|
hit.Type = HitType.Rim;
|
||||||
|
EndPlacement(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdatePosition(SnapResult result)
|
||||||
|
{
|
||||||
|
piece.Position = ToLocalSpace(result.ScreenSpacePosition);
|
||||||
|
base.UpdatePosition(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
osu.Game.Rulesets.Taiko/Edit/Blueprints/LengthPiece.cs
Normal file
40
osu.Game.Rulesets.Taiko/Edit/Blueprints/LengthPiece.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class LengthPiece : CompositeDrawable
|
||||||
|
{
|
||||||
|
public LengthPiece()
|
||||||
|
{
|
||||||
|
Origin = Anchor.CentreLeft;
|
||||||
|
|
||||||
|
InternalChild = new Container
|
||||||
|
{
|
||||||
|
Masking = true,
|
||||||
|
Colour = Color4.Yellow,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 8,
|
||||||
|
},
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class SwellPlacementBlueprint : TaikoSpanPlacementBlueprint
|
||||||
|
{
|
||||||
|
public SwellPlacementBlueprint()
|
||||||
|
: base(new Swell())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class TaikoSelectionBlueprint : OverlaySelectionBlueprint
|
||||||
|
{
|
||||||
|
public TaikoSelectionBlueprint(DrawableHitObject hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.None;
|
||||||
|
|
||||||
|
AddInternal(new HitPiece
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Origin = Anchor.TopLeft
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
// Move the rectangle to cover the hitobjects
|
||||||
|
var topLeft = new Vector2(float.MaxValue, float.MaxValue);
|
||||||
|
var bottomRight = new Vector2(float.MinValue, float.MinValue);
|
||||||
|
|
||||||
|
topLeft = Vector2.ComponentMin(topLeft, Parent.ToLocalSpace(DrawableObject.ScreenSpaceDrawQuad.TopLeft));
|
||||||
|
bottomRight = Vector2.ComponentMax(bottomRight, Parent.ToLocalSpace(DrawableObject.ScreenSpaceDrawQuad.BottomRight));
|
||||||
|
|
||||||
|
Size = bottomRight - topLeft;
|
||||||
|
Position = topLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class TaikoSpanPlacementBlueprint : PlacementBlueprint
|
||||||
|
{
|
||||||
|
private readonly HitPiece headPiece;
|
||||||
|
private readonly HitPiece tailPiece;
|
||||||
|
|
||||||
|
private readonly LengthPiece lengthPiece;
|
||||||
|
|
||||||
|
private readonly IHasDuration spanPlacementObject;
|
||||||
|
|
||||||
|
public TaikoSpanPlacementBlueprint(HitObject hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
spanPlacementObject = hitObject as IHasDuration;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
headPiece = new HitPiece
|
||||||
|
{
|
||||||
|
Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT)
|
||||||
|
},
|
||||||
|
lengthPiece = new LengthPiece
|
||||||
|
{
|
||||||
|
Height = TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT
|
||||||
|
},
|
||||||
|
tailPiece = new HitPiece
|
||||||
|
{
|
||||||
|
Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private double originalStartTime;
|
||||||
|
private Vector2 originalPosition;
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
|
{
|
||||||
|
if (e.Button != MouseButton.Left)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BeginPlacement(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseUp(MouseUpEvent e)
|
||||||
|
{
|
||||||
|
if (e.Button != MouseButton.Left)
|
||||||
|
return;
|
||||||
|
|
||||||
|
base.OnMouseUp(e);
|
||||||
|
EndPlacement(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdatePosition(SnapResult result)
|
||||||
|
{
|
||||||
|
base.UpdatePosition(result);
|
||||||
|
|
||||||
|
if (PlacementActive)
|
||||||
|
{
|
||||||
|
if (result.Time is double dragTime)
|
||||||
|
{
|
||||||
|
if (dragTime < originalStartTime)
|
||||||
|
{
|
||||||
|
HitObject.StartTime = dragTime;
|
||||||
|
spanPlacementObject.Duration = Math.Abs(dragTime - originalStartTime);
|
||||||
|
headPiece.Position = ToLocalSpace(result.ScreenSpacePosition);
|
||||||
|
tailPiece.Position = originalPosition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HitObject.StartTime = originalStartTime;
|
||||||
|
spanPlacementObject.Duration = Math.Abs(dragTime - originalStartTime);
|
||||||
|
tailPiece.Position = ToLocalSpace(result.ScreenSpacePosition);
|
||||||
|
headPiece.Position = originalPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
lengthPiece.X = headPiece.X;
|
||||||
|
lengthPiece.Width = tailPiece.X - headPiece.X;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lengthPiece.Position = headPiece.Position = tailPiece.Position = ToLocalSpace(result.ScreenSpacePosition);
|
||||||
|
|
||||||
|
if (result.Time is double startTime)
|
||||||
|
{
|
||||||
|
originalStartTime = HitObject.StartTime = startTime;
|
||||||
|
originalPosition = ToLocalSpace(result.ScreenSpacePosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
osu.Game.Rulesets.Taiko/Edit/DrumRollCompositionTool.cs
Normal file
20
osu.Game.Rulesets.Taiko/Edit/DrumRollCompositionTool.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
using osu.Game.Rulesets.Taiko.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit
|
||||||
|
{
|
||||||
|
public class DrumRollCompositionTool : HitObjectCompositionTool
|
||||||
|
{
|
||||||
|
public DrumRollCompositionTool()
|
||||||
|
: base(nameof(DrumRoll))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override PlacementBlueprint CreatePlacementBlueprint() => new DrumRollPlacementBlueprint();
|
||||||
|
}
|
||||||
|
}
|
20
osu.Game.Rulesets.Taiko/Edit/HitCompositionTool.cs
Normal file
20
osu.Game.Rulesets.Taiko/Edit/HitCompositionTool.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
using osu.Game.Rulesets.Taiko.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit
|
||||||
|
{
|
||||||
|
public class HitCompositionTool : HitObjectCompositionTool
|
||||||
|
{
|
||||||
|
public HitCompositionTool()
|
||||||
|
: base(nameof(Hit))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override PlacementBlueprint CreatePlacementBlueprint() => new HitPlacementBlueprint();
|
||||||
|
}
|
||||||
|
}
|
20
osu.Game.Rulesets.Taiko/Edit/SwellCompositionTool.cs
Normal file
20
osu.Game.Rulesets.Taiko/Edit/SwellCompositionTool.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
using osu.Game.Rulesets.Taiko.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit
|
||||||
|
{
|
||||||
|
public class SwellCompositionTool : HitObjectCompositionTool
|
||||||
|
{
|
||||||
|
public SwellCompositionTool()
|
||||||
|
: base(nameof(Swell))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override PlacementBlueprint CreatePlacementBlueprint() => new SwellPlacementBlueprint();
|
||||||
|
}
|
||||||
|
}
|
24
osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs
Normal file
24
osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Taiko.Edit.Blueprints;
|
||||||
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit
|
||||||
|
{
|
||||||
|
public class TaikoBlueprintContainer : ComposeBlueprintContainer
|
||||||
|
{
|
||||||
|
public TaikoBlueprintContainer(IEnumerable<DrawableHitObject> hitObjects)
|
||||||
|
: base(hitObjects)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override SelectionHandler CreateSelectionHandler() => new TaikoSelectionHandler();
|
||||||
|
|
||||||
|
public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) =>
|
||||||
|
new TaikoSelectionBlueprint(hitObject);
|
||||||
|
}
|
||||||
|
}
|
30
osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs
Normal file
30
osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit
|
||||||
|
{
|
||||||
|
public class TaikoHitObjectComposer : HitObjectComposer<TaikoHitObject>
|
||||||
|
{
|
||||||
|
public TaikoHitObjectComposer(TaikoRuleset ruleset)
|
||||||
|
: base(ruleset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
||||||
|
{
|
||||||
|
new HitCompositionTool(),
|
||||||
|
new DrumRollCompositionTool(),
|
||||||
|
new SwellCompositionTool()
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override ComposeBlueprintContainer CreateBlueprintContainer(IEnumerable<DrawableHitObject> hitObjects)
|
||||||
|
=> new TaikoBlueprintContainer(hitObjects);
|
||||||
|
}
|
||||||
|
}
|
80
osu.Game.Rulesets.Taiko/Edit/TaikoSelectionHandler.cs
Normal file
80
osu.Game.Rulesets.Taiko/Edit/TaikoSelectionHandler.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Edit
|
||||||
|
{
|
||||||
|
public class TaikoSelectionHandler : SelectionHandler
|
||||||
|
{
|
||||||
|
protected override IEnumerable<MenuItem> GetContextMenuItemsForSelection(IEnumerable<SelectionBlueprint> selection)
|
||||||
|
{
|
||||||
|
if (selection.All(s => s.HitObject is Hit))
|
||||||
|
{
|
||||||
|
var hits = selection.Select(s => s.HitObject).OfType<Hit>();
|
||||||
|
|
||||||
|
yield return new TernaryStateMenuItem("Rim", action: state =>
|
||||||
|
{
|
||||||
|
foreach (var h in hits)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case TernaryState.True:
|
||||||
|
h.Type = HitType.Rim;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TernaryState.False:
|
||||||
|
h.Type = HitType.Centre;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
{
|
||||||
|
State = { Value = getTernaryState(hits, h => h.Type == HitType.Rim) }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selection.All(s => s.HitObject is TaikoHitObject))
|
||||||
|
{
|
||||||
|
var hits = selection.Select(s => s.HitObject).OfType<TaikoHitObject>();
|
||||||
|
|
||||||
|
yield return new TernaryStateMenuItem("Strong", action: state =>
|
||||||
|
{
|
||||||
|
foreach (var h in hits)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case TernaryState.True:
|
||||||
|
h.IsStrong = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TernaryState.False:
|
||||||
|
h.IsStrong = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorBeatmap?.UpdateHitObject(h);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
{
|
||||||
|
State = { Value = getTernaryState(hits, h => h.IsStrong) }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TernaryState getTernaryState<T>(IEnumerable<T> selection, Func<T, bool> func)
|
||||||
|
{
|
||||||
|
if (selection.Any(func))
|
||||||
|
return selection.All(func) ? TernaryState.True : TernaryState.Indeterminate;
|
||||||
|
|
||||||
|
return TernaryState.False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -48,12 +48,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
colourIdle = colours.YellowDark;
|
colourIdle = colours.YellowDark;
|
||||||
colourEngaged = colours.YellowDarker;
|
colourEngaged = colours.YellowDarker;
|
||||||
|
|
||||||
updateColour();
|
Content.Add(tickContainer = new Container
|
||||||
|
{
|
||||||
Content.Add(tickContainer = new Container { RelativeSizeAxes = Axes.Both });
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Depth = float.MinValue
|
||||||
if (MainPiece.Drawable is IHasAccentColour accentMain)
|
});
|
||||||
accentMain.AccentColour = colourIdle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -63,6 +62,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
OnNewResult += onNewResult;
|
OnNewResult += onNewResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void RecreatePieces()
|
||||||
|
{
|
||||||
|
base.RecreatePieces();
|
||||||
|
updateColour();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
base.AddNestedHitObject(hitObject);
|
base.AddNestedHitObject(hitObject);
|
||||||
|
@ -5,6 +5,8 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@ -19,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of keys which can result in hits for this HitObject.
|
/// A list of keys which can result in hits for this HitObject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TaikoAction[] HitActions { get; }
|
public TaikoAction[] HitActions { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The action that caused this <see cref="DrawableHit"/> to be hit.
|
/// The action that caused this <see cref="DrawableHit"/> to be hit.
|
||||||
@ -34,15 +36,35 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
|
|
||||||
private bool pressHandledThisFrame;
|
private bool pressHandledThisFrame;
|
||||||
|
|
||||||
|
private Bindable<HitType> type;
|
||||||
|
|
||||||
public DrawableHit(Hit hit)
|
public DrawableHit(Hit hit)
|
||||||
: base(hit)
|
: base(hit)
|
||||||
{
|
{
|
||||||
FillMode = FillMode.Fit;
|
FillMode = FillMode.Fit;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
type = HitObject.TypeBindable.GetBoundCopy();
|
||||||
|
type.BindValueChanged(_ =>
|
||||||
|
{
|
||||||
|
updateType();
|
||||||
|
RecreatePieces();
|
||||||
|
});
|
||||||
|
|
||||||
|
updateType();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateType()
|
||||||
|
{
|
||||||
HitActions =
|
HitActions =
|
||||||
HitObject.Type == HitType.Centre
|
HitObject.Type == HitType.Centre
|
||||||
? new[] { TaikoAction.LeftCentre, TaikoAction.RightCentre }
|
? new[] { TaikoAction.LeftCentre, TaikoAction.RightCentre }
|
||||||
: new[] { TaikoAction.LeftRim, TaikoAction.RightRim };
|
: new[] { TaikoAction.LeftRim, TaikoAction.RightRim };
|
||||||
|
|
||||||
|
RecreatePieces();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override SkinnableDrawable CreateMainPiece() => HitObject.Type == HitType.Centre
|
protected override SkinnableDrawable CreateMainPiece() => HitObject.Type == HitType.Centre
|
||||||
|
@ -8,6 +8,8 @@ using osuTK;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -115,8 +117,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
|
|
||||||
public new TObject HitObject;
|
public new TObject HitObject;
|
||||||
|
|
||||||
protected readonly Vector2 BaseSize;
|
protected Vector2 BaseSize;
|
||||||
protected readonly SkinnableDrawable MainPiece;
|
protected SkinnableDrawable MainPiece;
|
||||||
|
|
||||||
|
private Bindable<bool> isStrong;
|
||||||
|
|
||||||
private readonly Container<DrawableStrongNestedHit> strongHitContainer;
|
private readonly Container<DrawableStrongNestedHit> strongHitContainer;
|
||||||
|
|
||||||
@ -129,13 +133,25 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
Origin = Anchor.Custom;
|
Origin = Anchor.Custom;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
Size = BaseSize = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
|
|
||||||
|
|
||||||
Content.Add(MainPiece = CreateMainPiece());
|
|
||||||
|
|
||||||
AddInternal(strongHitContainer = new Container<DrawableStrongNestedHit>());
|
AddInternal(strongHitContainer = new Container<DrawableStrongNestedHit>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
isStrong = HitObject.IsStrongBindable.GetBoundCopy();
|
||||||
|
isStrong.BindValueChanged(_ => RecreatePieces(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void RecreatePieces()
|
||||||
|
{
|
||||||
|
Size = BaseSize = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
|
||||||
|
|
||||||
|
MainPiece?.Expire();
|
||||||
|
Content.Add(MainPiece = CreateMainPiece());
|
||||||
|
}
|
||||||
|
|
||||||
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
base.AddNestedHitObject(hitObject);
|
base.AddNestedHitObject(hitObject);
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects
|
namespace osu.Game.Rulesets.Taiko.Objects
|
||||||
{
|
{
|
||||||
public class Hit : TaikoHitObject
|
public class Hit : TaikoHitObject
|
||||||
{
|
{
|
||||||
|
public readonly Bindable<HitType> TypeBindable = new Bindable<HitType>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="HitType"/> that actuates this <see cref="Hit"/>.
|
/// The <see cref="HitType"/> that actuates this <see cref="Hit"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public HitType Type { get; set; }
|
public HitType Type
|
||||||
|
{
|
||||||
|
get => TypeBindable.Value;
|
||||||
|
set => TypeBindable.Value = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
@ -25,11 +24,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int RequiredHits = 10;
|
public int RequiredHits = 10;
|
||||||
|
|
||||||
public override bool IsStrong
|
|
||||||
{
|
|
||||||
set => throw new NotSupportedException($"{nameof(Swell)} cannot be a strong hitobject.");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
|
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
base.CreateNestedHitObjects(cancellationToken);
|
base.CreateNestedHitObjects(cancellationToken);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -27,11 +28,17 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
|
public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
|
||||||
|
|
||||||
|
public readonly Bindable<bool> IsStrongBindable = new BindableBool();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this HitObject is a "strong" type.
|
/// Whether this HitObject is a "strong" type.
|
||||||
/// Strong hit objects give more points for hitting the hit object with both keys.
|
/// Strong hit objects give more points for hitting the hit object with both keys.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual bool IsStrong { get; set; }
|
public bool IsStrong
|
||||||
|
{
|
||||||
|
get => IsStrongBindable.Value;
|
||||||
|
set => IsStrongBindable.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
|
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,8 @@ using osu.Game.Rulesets.Taiko.Difficulty;
|
|||||||
using osu.Game.Rulesets.Taiko.Scoring;
|
using osu.Game.Rulesets.Taiko.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using System;
|
using System;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Taiko.Edit;
|
||||||
using osu.Game.Rulesets.Taiko.Skinning;
|
using osu.Game.Rulesets.Taiko.Skinning;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
@ -144,6 +146,8 @@ namespace osu.Game.Rulesets.Taiko
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetTaiko };
|
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetTaiko };
|
||||||
|
|
||||||
|
public override HitObjectComposer CreateHitObjectComposer() => new TaikoHitObjectComposer(this);
|
||||||
|
|
||||||
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap);
|
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap);
|
||||||
|
|
||||||
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new TaikoPerformanceCalculator(this, beatmap, score);
|
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new TaikoPerformanceCalculator(this, beatmap, score);
|
||||||
|
@ -11,23 +11,13 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class TernaryStateMenuItem : StatefulMenuItem<TernaryState>
|
public class TernaryStateMenuItem : StatefulMenuItem<TernaryState>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Creates a new <see cref="TernaryStateMenuItem"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text">The text to display.</param>
|
|
||||||
/// <param name="type">The type of action which this <see cref="TernaryStateMenuItem"/> performs.</param>
|
|
||||||
public TernaryStateMenuItem(string text, MenuItemType type = MenuItemType.Standard)
|
|
||||||
: this(text, type, null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="TernaryStateMenuItem"/>.
|
/// Creates a new <see cref="TernaryStateMenuItem"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The text to display.</param>
|
/// <param name="text">The text to display.</param>
|
||||||
/// <param name="type">The type of action which this <see cref="TernaryStateMenuItem"/> performs.</param>
|
/// <param name="type">The type of action which this <see cref="TernaryStateMenuItem"/> performs.</param>
|
||||||
/// <param name="action">A delegate to be invoked when this <see cref="TernaryStateMenuItem"/> is pressed.</param>
|
/// <param name="action">A delegate to be invoked when this <see cref="TernaryStateMenuItem"/> is pressed.</param>
|
||||||
public TernaryStateMenuItem(string text, MenuItemType type, Action<TernaryState> action)
|
public TernaryStateMenuItem(string text, MenuItemType type = MenuItemType.Standard, Action<TernaryState> action = null)
|
||||||
: this(text, getNextState, type, action)
|
: this(text, getNextState, type, action)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -87,11 +87,11 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the position of this <see cref="PlacementBlueprint"/> to a new screen-space position.
|
/// Updates the position of this <see cref="PlacementBlueprint"/> to a new screen-space position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="snapResult">The snap result information.</param>
|
/// <param name="result">The snap result information.</param>
|
||||||
public virtual void UpdatePosition(SnapResult snapResult)
|
public virtual void UpdatePosition(SnapResult result)
|
||||||
{
|
{
|
||||||
if (!PlacementActive)
|
if (!PlacementActive)
|
||||||
HitObject.StartTime = snapResult.Time ?? EditorClock?.CurrentTime ?? Time.Current;
|
HitObject.StartTime = result.Time ?? EditorClock?.CurrentTime ?? Time.Current;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
private Drawable outline;
|
private Drawable outline;
|
||||||
|
|
||||||
[Resolved(CanBeNull = true)]
|
[Resolved(CanBeNull = true)]
|
||||||
private EditorBeatmap editorBeatmap { get; set; }
|
protected EditorBeatmap EditorBeatmap { get; private set; }
|
||||||
|
|
||||||
[Resolved(CanBeNull = true)]
|
[Resolved(CanBeNull = true)]
|
||||||
private IEditorChangeHandler changeHandler { get; set; }
|
private IEditorChangeHandler changeHandler { get; set; }
|
||||||
@ -117,7 +117,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
internal void HandleSelected(SelectionBlueprint blueprint)
|
internal void HandleSelected(SelectionBlueprint blueprint)
|
||||||
{
|
{
|
||||||
selectedBlueprints.Add(blueprint);
|
selectedBlueprints.Add(blueprint);
|
||||||
editorBeatmap.SelectedHitObjects.Add(blueprint.HitObject);
|
EditorBeatmap.SelectedHitObjects.Add(blueprint.HitObject);
|
||||||
|
|
||||||
UpdateVisibility();
|
UpdateVisibility();
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
internal void HandleDeselected(SelectionBlueprint blueprint)
|
internal void HandleDeselected(SelectionBlueprint blueprint)
|
||||||
{
|
{
|
||||||
selectedBlueprints.Remove(blueprint);
|
selectedBlueprints.Remove(blueprint);
|
||||||
editorBeatmap.SelectedHitObjects.Remove(blueprint.HitObject);
|
EditorBeatmap.SelectedHitObjects.Remove(blueprint.HitObject);
|
||||||
|
|
||||||
// We don't want to update visibility if > 0, since we may be deselecting blueprints during drag-selection
|
// We don't want to update visibility if > 0, since we may be deselecting blueprints during drag-selection
|
||||||
if (selectedBlueprints.Count == 0)
|
if (selectedBlueprints.Count == 0)
|
||||||
@ -165,7 +165,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
changeHandler?.BeginChange();
|
changeHandler?.BeginChange();
|
||||||
|
|
||||||
foreach (var h in selectedBlueprints.ToList())
|
foreach (var h in selectedBlueprints.ToList())
|
||||||
editorBeatmap?.Remove(h.HitObject);
|
EditorBeatmap?.Remove(h.HitObject);
|
||||||
|
|
||||||
changeHandler?.EndChange();
|
changeHandler?.EndChange();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user