mirror of
https://github.com/ppy/osu.git
synced 2024-11-15 12:27:26 +08:00
Merge pull request #29986 from OliBomby/refactor-placement-tool
Refactor placement blueprints to not be limited to hit objects
This commit is contained in:
commit
3111d6a74d
@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
|
|||||||
contentContainer.Playfield.HitObjectContainer.Add(hitObject);
|
contentContainer.Playfield.HitObjectContainer.Add(hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override SnapResult SnapForBlueprint(PlacementBlueprint blueprint)
|
protected override SnapResult SnapForBlueprint(HitObjectPlacementBlueprint blueprint)
|
||||||
{
|
{
|
||||||
var result = base.SnapForBlueprint(blueprint);
|
var result = base.SnapForBlueprint(blueprint);
|
||||||
result.Time = Math.Round(HitObjectContainer.TimeAtScreenSpacePosition(result.ScreenSpacePosition) / TIME_SNAP) * TIME_SNAP;
|
result.Time = Math.Round(HitObjectContainer.TimeAtScreenSpacePosition(result.ScreenSpacePosition) / TIME_SNAP) * TIME_SNAP;
|
||||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
|
|||||||
{
|
{
|
||||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableBananaShower((BananaShower)hitObject);
|
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableBananaShower((BananaShower)hitObject);
|
||||||
|
|
||||||
protected override PlacementBlueprint CreateBlueprint() => new BananaShowerPlacementBlueprint();
|
protected override HitObjectPlacementBlueprint CreateBlueprint() => new BananaShowerPlacementBlueprint();
|
||||||
|
|
||||||
protected override void AddHitObject(DrawableHitObject hitObject)
|
protected override void AddHitObject(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
|
|||||||
{
|
{
|
||||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableFruit((Fruit)hitObject);
|
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableFruit((Fruit)hitObject);
|
||||||
|
|
||||||
protected override PlacementBlueprint CreateBlueprint() => new FruitPlacementBlueprint();
|
protected override HitObjectPlacementBlueprint CreateBlueprint() => new FruitPlacementBlueprint();
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestFruitPlacementPosition()
|
public void TestFruitPlacementPosition()
|
||||||
|
@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
|
|||||||
|
|
||||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableJuiceStream((JuiceStream)hitObject);
|
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableJuiceStream((JuiceStream)hitObject);
|
||||||
|
|
||||||
protected override PlacementBlueprint CreateBlueprint() => new JuiceStreamPlacementBlueprint();
|
protected override HitObjectPlacementBlueprint CreateBlueprint() => new JuiceStreamPlacementBlueprint();
|
||||||
|
|
||||||
private void addMoveAndClickSteps(double time, float position, bool end = false)
|
private void addMoveAndClickSteps(double time, float position, bool end = false)
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Edit.Tools;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Edit
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
{
|
{
|
||||||
public class BananaShowerCompositionTool : HitObjectCompositionTool
|
public class BananaShowerCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public BananaShowerCompositionTool()
|
public BananaShowerCompositionTool()
|
||||||
: base(nameof(BananaShower))
|
: base(nameof(BananaShower))
|
||||||
@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new BananaShowerPlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new BananaShowerPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ using osu.Game.Rulesets.UI.Scrolling;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||||
{
|
{
|
||||||
public partial class CatchPlacementBlueprint<THitObject> : PlacementBlueprint
|
public partial class CatchPlacementBlueprint<THitObject> : HitObjectPlacementBlueprint
|
||||||
where THitObject : CatchHitObject, new()
|
where THitObject : CatchHitObject, new()
|
||||||
{
|
{
|
||||||
protected new THitObject HitObject => (THitObject)base.HitObject;
|
protected new THitObject HitObject => (THitObject)base.HitObject;
|
||||||
|
@ -84,7 +84,7 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
|
|
||||||
protected override BeatSnapGrid CreateBeatSnapGrid() => new CatchBeatSnapGrid();
|
protected override BeatSnapGrid CreateBeatSnapGrid() => new CatchBeatSnapGrid();
|
||||||
|
|
||||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
protected override IReadOnlyList<CompositionTool> CompositionTools => new CompositionTool[]
|
||||||
{
|
{
|
||||||
new FruitCompositionTool(),
|
new FruitCompositionTool(),
|
||||||
new JuiceStreamCompositionTool(),
|
new JuiceStreamCompositionTool(),
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Edit.Tools;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Edit
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
{
|
{
|
||||||
public class FruitCompositionTool : HitObjectCompositionTool
|
public class FruitCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public FruitCompositionTool()
|
public FruitCompositionTool()
|
||||||
: base(nameof(Fruit))
|
: base(nameof(Fruit))
|
||||||
@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new FruitPlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new FruitPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Edit.Tools;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Edit
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
{
|
{
|
||||||
public class JuiceStreamCompositionTool : HitObjectCompositionTool
|
public class JuiceStreamCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public JuiceStreamCompositionTool()
|
public JuiceStreamCompositionTool()
|
||||||
: base(nameof(JuiceStream))
|
: base(nameof(JuiceStream))
|
||||||
@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new JuiceStreamPlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new JuiceStreamPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override SnapResult SnapForBlueprint(PlacementBlueprint blueprint)
|
protected override SnapResult SnapForBlueprint(HitObjectPlacementBlueprint blueprint)
|
||||||
{
|
{
|
||||||
double time = column.TimeAtScreenSpacePosition(InputManager.CurrentState.Mouse.Position);
|
double time = column.TimeAtScreenSpacePosition(InputManager.CurrentState.Mouse.Position);
|
||||||
var pos = column.ScreenSpacePositionAtTime(time);
|
var pos = column.ScreenSpacePositionAtTime(time);
|
||||||
|
@ -13,6 +13,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
|
|||||||
public partial class TestSceneHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestScene
|
public partial class TestSceneHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestScene
|
||||||
{
|
{
|
||||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHoldNote((HoldNote)hitObject);
|
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHoldNote((HoldNote)hitObject);
|
||||||
protected override PlacementBlueprint CreateBlueprint() => new HoldNotePlacementBlueprint();
|
protected override HitObjectPlacementBlueprint CreateBlueprint() => new HoldNotePlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
|
|||||||
private Note getNote() => this.ChildrenOfType<DrawableNote>().FirstOrDefault()?.HitObject;
|
private Note getNote() => this.ChildrenOfType<DrawableNote>().FirstOrDefault()?.HitObject;
|
||||||
|
|
||||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableNote((Note)hitObject);
|
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableNote((Note)hitObject);
|
||||||
protected override PlacementBlueprint CreateBlueprint() => new NotePlacementBlueprint();
|
protected override HitObjectPlacementBlueprint CreateBlueprint() => new NotePlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ using osuTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||||
{
|
{
|
||||||
public abstract partial class ManiaPlacementBlueprint<T> : PlacementBlueprint
|
public abstract partial class ManiaPlacementBlueprint<T> : HitObjectPlacementBlueprint
|
||||||
where T : ManiaHitObject
|
where T : ManiaHitObject
|
||||||
{
|
{
|
||||||
protected new T HitObject => (T)base.HitObject;
|
protected new T HitObject => (T)base.HitObject;
|
||||||
|
@ -9,7 +9,7 @@ using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
{
|
{
|
||||||
public class HoldNoteCompositionTool : HitObjectCompositionTool
|
public class HoldNoteCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public HoldNoteCompositionTool()
|
public HoldNoteCompositionTool()
|
||||||
: base("Hold")
|
: base("Hold")
|
||||||
@ -18,6 +18,6 @@ namespace osu.Game.Rulesets.Mania.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new HoldNotePlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new HoldNotePlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
|||||||
|
|
||||||
protected override BeatSnapGrid CreateBeatSnapGrid() => new ManiaBeatSnapGrid();
|
protected override BeatSnapGrid CreateBeatSnapGrid() => new ManiaBeatSnapGrid();
|
||||||
|
|
||||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
protected override IReadOnlyList<CompositionTool> CompositionTools => new CompositionTool[]
|
||||||
{
|
{
|
||||||
new NoteCompositionTool(),
|
new NoteCompositionTool(),
|
||||||
new HoldNoteCompositionTool()
|
new HoldNoteCompositionTool()
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Mania.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
{
|
{
|
||||||
public class NoteCompositionTool : HitObjectCompositionTool
|
public class NoteCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public NoteCompositionTool()
|
public NoteCompositionTool()
|
||||||
: base(nameof(Note))
|
: base(nameof(Note))
|
||||||
@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Mania.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new NotePlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new NotePlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
public partial class TestSceneHitCirclePlacementBlueprint : PlacementBlueprintTestScene
|
public partial class TestSceneHitCirclePlacementBlueprint : PlacementBlueprintTestScene
|
||||||
{
|
{
|
||||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHitCircle((HitCircle)hitObject);
|
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHitCircle((HitCircle)hitObject);
|
||||||
protected override PlacementBlueprint CreateBlueprint() => new HitCirclePlacementBlueprint();
|
protected override HitObjectPlacementBlueprint CreateBlueprint() => new HitCirclePlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -514,6 +514,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
private Slider? getSlider() => HitObjectContainer.Count > 0 ? ((DrawableSlider)HitObjectContainer[0]).HitObject : null;
|
private Slider? getSlider() => HitObjectContainer.Count > 0 ? ((DrawableSlider)HitObjectContainer[0]).HitObject : null;
|
||||||
|
|
||||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSlider((Slider)hitObject);
|
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSlider((Slider)hitObject);
|
||||||
protected override PlacementBlueprint CreateBlueprint() => new SliderPlacementBlueprint();
|
protected override HitObjectPlacementBlueprint CreateBlueprint() => new SliderPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
{
|
{
|
||||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSpinner((Spinner)hitObject);
|
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSpinner((Spinner)hitObject);
|
||||||
|
|
||||||
protected override PlacementBlueprint CreateBlueprint() => new SpinnerPlacementBlueprint();
|
protected override HitObjectPlacementBlueprint CreateBlueprint() => new SpinnerPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ using osuTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles
|
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles
|
||||||
{
|
{
|
||||||
public partial class HitCirclePlacementBlueprint : PlacementBlueprint
|
public partial class HitCirclePlacementBlueprint : HitObjectPlacementBlueprint
|
||||||
{
|
{
|
||||||
public new HitCircle HitObject => (HitCircle)base.HitObject;
|
public new HitCircle HitObject => (HitCircle)base.HitObject;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ using osuTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
||||||
{
|
{
|
||||||
public partial class SliderPlacementBlueprint : PlacementBlueprint
|
public partial class SliderPlacementBlueprint : HitObjectPlacementBlueprint
|
||||||
{
|
{
|
||||||
public new Slider HitObject => (Slider)base.HitObject;
|
public new Slider HitObject => (Slider)base.HitObject;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ using osuTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
|
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
|
||||||
{
|
{
|
||||||
public partial class SpinnerPlacementBlueprint : PlacementBlueprint
|
public partial class SpinnerPlacementBlueprint : HitObjectPlacementBlueprint
|
||||||
{
|
{
|
||||||
public new Spinner HitObject => (Spinner)base.HitObject;
|
public new Spinner HitObject => (Spinner)base.HitObject;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Osu.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit
|
namespace osu.Game.Rulesets.Osu.Edit
|
||||||
{
|
{
|
||||||
public class HitCircleCompositionTool : HitObjectCompositionTool
|
public class HitCircleCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public HitCircleCompositionTool()
|
public HitCircleCompositionTool()
|
||||||
: base(nameof(HitCircle))
|
: base(nameof(HitCircle))
|
||||||
@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new HitCirclePlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new HitCirclePlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
protected override DrawableRuleset<OsuHitObject> CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods)
|
protected override DrawableRuleset<OsuHitObject> CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||||
=> new DrawableOsuEditorRuleset(ruleset, beatmap, mods);
|
=> new DrawableOsuEditorRuleset(ruleset, beatmap, mods);
|
||||||
|
|
||||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
protected override IReadOnlyList<CompositionTool> CompositionTools => new CompositionTool[]
|
||||||
{
|
{
|
||||||
new HitCircleCompositionTool(),
|
new HitCircleCompositionTool(),
|
||||||
new SliderCompositionTool(),
|
new SliderCompositionTool(),
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Osu.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit
|
namespace osu.Game.Rulesets.Osu.Edit
|
||||||
{
|
{
|
||||||
public class SliderCompositionTool : HitObjectCompositionTool
|
public class SliderCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public SliderCompositionTool()
|
public SliderCompositionTool()
|
||||||
: base(nameof(Slider))
|
: base(nameof(Slider))
|
||||||
@ -26,6 +26,6 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new SliderPlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new SliderPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Osu.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit
|
namespace osu.Game.Rulesets.Osu.Edit
|
||||||
{
|
{
|
||||||
public class SpinnerCompositionTool : HitObjectCompositionTool
|
public class SpinnerCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public SpinnerCompositionTool()
|
public SpinnerCompositionTool()
|
||||||
: base(nameof(Spinner))
|
: base(nameof(Spinner))
|
||||||
@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new SpinnerPlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new SpinnerPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ using osuTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||||
{
|
{
|
||||||
public partial class HitPlacementBlueprint : PlacementBlueprint
|
public partial class HitPlacementBlueprint : HitObjectPlacementBlueprint
|
||||||
{
|
{
|
||||||
private readonly HitPiece piece;
|
private readonly HitPiece piece;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ using osuTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||||
{
|
{
|
||||||
public partial class TaikoSpanPlacementBlueprint : PlacementBlueprint
|
public partial class TaikoSpanPlacementBlueprint : HitObjectPlacementBlueprint
|
||||||
{
|
{
|
||||||
private readonly HitPiece headPiece;
|
private readonly HitPiece headPiece;
|
||||||
private readonly HitPiece tailPiece;
|
private readonly HitPiece tailPiece;
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Taiko.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Edit
|
namespace osu.Game.Rulesets.Taiko.Edit
|
||||||
{
|
{
|
||||||
public class DrumRollCompositionTool : HitObjectCompositionTool
|
public class DrumRollCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public DrumRollCompositionTool()
|
public DrumRollCompositionTool()
|
||||||
: base(nameof(DrumRoll))
|
: base(nameof(DrumRoll))
|
||||||
@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Taiko.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new DrumRollPlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new DrumRollPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Taiko.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Edit
|
namespace osu.Game.Rulesets.Taiko.Edit
|
||||||
{
|
{
|
||||||
public class HitCompositionTool : HitObjectCompositionTool
|
public class HitCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public HitCompositionTool()
|
public HitCompositionTool()
|
||||||
: base(nameof(Hit))
|
: base(nameof(Hit))
|
||||||
@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Taiko.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new HitPlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new HitPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Taiko.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Edit
|
namespace osu.Game.Rulesets.Taiko.Edit
|
||||||
{
|
{
|
||||||
public class SwellCompositionTool : HitObjectCompositionTool
|
public class SwellCompositionTool : CompositionTool
|
||||||
{
|
{
|
||||||
public SwellCompositionTool()
|
public SwellCompositionTool()
|
||||||
: base(nameof(Swell))
|
: base(nameof(Swell))
|
||||||
@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Taiko.Edit
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners);
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners);
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => new SwellPlacementBlueprint();
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => new SwellPlacementBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.Edit
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
protected override IReadOnlyList<CompositionTool> CompositionTools => new CompositionTool[]
|
||||||
{
|
{
|
||||||
new HitCompositionTool(),
|
new HitCompositionTool(),
|
||||||
new DrumRollCompositionTool(),
|
new DrumRollCompositionTool(),
|
||||||
|
@ -323,7 +323,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// A "select" tool is automatically added as the first tool.
|
/// A "select" tool is automatically added as the first tool.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
protected abstract IReadOnlyList<CompositionTool> CompositionTools { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A collection of states which will be displayed to the user in the toolbox.
|
/// A collection of states which will be displayed to the user in the toolbox.
|
||||||
@ -466,7 +466,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
private void setSelectTool() => toolboxCollection.Items.First().Select();
|
private void setSelectTool() => toolboxCollection.Items.First().Select();
|
||||||
|
|
||||||
private void toolSelected(HitObjectCompositionTool tool)
|
private void toolSelected(CompositionTool tool)
|
||||||
{
|
{
|
||||||
BlueprintContainer.CurrentTool = tool;
|
BlueprintContainer.CurrentTool = tool;
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
{
|
{
|
||||||
public class HitObjectCompositionToolButton : RadioButton
|
public class HitObjectCompositionToolButton : RadioButton
|
||||||
{
|
{
|
||||||
public HitObjectCompositionTool Tool { get; }
|
public CompositionTool Tool { get; }
|
||||||
|
|
||||||
public HitObjectCompositionToolButton(HitObjectCompositionTool tool, Action? action)
|
public HitObjectCompositionToolButton(CompositionTool tool, Action? action)
|
||||||
: base(tool.Name, action, tool.CreateIcon)
|
: base(tool.Name, action, tool.CreateIcon)
|
||||||
{
|
{
|
||||||
Tool = tool;
|
Tool = tool;
|
||||||
|
126
osu.Game/Rulesets/Edit/HitObjectPlacementBlueprint.cs
Normal file
126
osu.Game/Rulesets/Edit/HitObjectPlacementBlueprint.cs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Audio;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Screens.Edit;
|
||||||
|
using osu.Game.Screens.Edit.Compose;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Edit
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A blueprint which governs the creation of a new <see cref="HitObject"/> to actualisation.
|
||||||
|
/// </summary>
|
||||||
|
public abstract partial class HitObjectPlacementBlueprint : PlacementBlueprint
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the sample bank should be taken from the previous hit object.
|
||||||
|
/// </summary>
|
||||||
|
public bool AutomaticBankAssignment { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="HitObject"/> that is being placed.
|
||||||
|
/// </summary>
|
||||||
|
public readonly HitObject HitObject;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
protected EditorClock EditorClock { get; private set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private EditorBeatmap beatmap { get; set; } = null!;
|
||||||
|
|
||||||
|
private Bindable<double> startTimeBindable = null!;
|
||||||
|
|
||||||
|
private HitObject? getPreviousHitObject() => beatmap.HitObjects.TakeWhile(h => h.StartTime <= startTimeBindable.Value).LastOrDefault();
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IPlacementHandler placementHandler { get; set; } = null!;
|
||||||
|
|
||||||
|
protected HitObjectPlacementBlueprint(HitObject hitObject)
|
||||||
|
{
|
||||||
|
HitObject = hitObject;
|
||||||
|
|
||||||
|
// adding the default hit sample should be the case regardless of the ruleset.
|
||||||
|
HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_NORMAL));
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
startTimeBindable = HitObject.StartTimeBindable.GetBoundCopy();
|
||||||
|
startTimeBindable.BindValueChanged(_ => ApplyDefaultsToHitObject(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void BeginPlacement(bool commitStart = false)
|
||||||
|
{
|
||||||
|
base.BeginPlacement(commitStart);
|
||||||
|
|
||||||
|
placementHandler.BeginPlacement(HitObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EndPlacement(bool commit)
|
||||||
|
{
|
||||||
|
base.EndPlacement(commit);
|
||||||
|
|
||||||
|
placementHandler.EndPlacement(HitObject, IsValidForPlacement && commit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the time and position of this <see cref="HitObjectPlacementBlueprint"/> based on the provided snap information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="result">The snap result information.</param>
|
||||||
|
public override void UpdateTimeAndPosition(SnapResult result)
|
||||||
|
{
|
||||||
|
if (PlacementActive == PlacementState.Waiting)
|
||||||
|
{
|
||||||
|
HitObject.StartTime = result.Time ?? EditorClock.CurrentTime;
|
||||||
|
|
||||||
|
if (HitObject is IHasComboInformation comboInformation)
|
||||||
|
comboInformation.UpdateComboInformation(getPreviousHitObject() as IHasComboInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastHitObject = getPreviousHitObject();
|
||||||
|
|
||||||
|
if (AutomaticBankAssignment)
|
||||||
|
{
|
||||||
|
// Create samples based on the sample settings of the previous hit object
|
||||||
|
if (lastHitObject != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < HitObject.Samples.Count; i++)
|
||||||
|
HitObject.Samples[i] = lastHitObject.CreateHitSampleInfo(HitObject.Samples[i].Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var lastHitNormal = lastHitObject?.Samples?.FirstOrDefault(o => o.Name == HitSampleInfo.HIT_NORMAL);
|
||||||
|
|
||||||
|
if (lastHitNormal != null)
|
||||||
|
{
|
||||||
|
// Only inherit the volume from the previous hit object
|
||||||
|
for (int i = 0; i < HitObject.Samples.Count; i++)
|
||||||
|
HitObject.Samples[i] = HitObject.Samples[i].With(newVolume: lastHitNormal.Volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HitObject is IHasRepeats hasRepeats)
|
||||||
|
{
|
||||||
|
// Make sure all the node samples are identical to the hit object's samples
|
||||||
|
for (int i = 0; i < hasRepeats.NodeSamples.Count; i++)
|
||||||
|
hasRepeats.NodeSamples[i] = HitObject.Samples.Select(o => o.With()).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes <see cref="Objects.HitObject.ApplyDefaults(ControlPointInfo,IBeatmapDifficultyInfo,CancellationToken)"/>,
|
||||||
|
/// refreshing <see cref="Objects.HitObject.NestedHitObjects"/> and parameters for the <see cref="HitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected void ApplyDefaultsToHitObject() => HitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.Difficulty);
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +1,19 @@
|
|||||||
// 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.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Audio;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
|
||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Screens.Edit;
|
|
||||||
using osu.Game.Screens.Edit.Compose;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit
|
namespace osu.Game.Rulesets.Edit
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A blueprint which governs the creation of a new <see cref="HitObject"/> to actualisation.
|
/// A blueprint which governs the placement of something.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract partial class PlacementBlueprint : CompositeDrawable, IKeyBindingHandler<GlobalAction>
|
public abstract partial class PlacementBlueprint : CompositeDrawable, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
@ -32,29 +22,6 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public PlacementState PlacementActive { get; private set; }
|
public PlacementState PlacementActive { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the sample bank should be taken from the previous hit object.
|
|
||||||
/// </summary>
|
|
||||||
public bool AutomaticBankAssignment { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The <see cref="HitObject"/> that is being placed.
|
|
||||||
/// </summary>
|
|
||||||
public readonly HitObject HitObject;
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
protected EditorClock EditorClock { get; private set; } = null!;
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private EditorBeatmap beatmap { get; set; } = null!;
|
|
||||||
|
|
||||||
private Bindable<double> startTimeBindable = null!;
|
|
||||||
|
|
||||||
private HitObject? getPreviousHitObject() => beatmap.HitObjects.TakeWhile(h => h.StartTime <= startTimeBindable.Value).LastOrDefault();
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private IPlacementHandler placementHandler { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this blueprint is currently in a state that can be committed.
|
/// Whether this blueprint is currently in a state that can be committed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -64,13 +31,8 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected virtual bool IsValidForPlacement => true;
|
protected virtual bool IsValidForPlacement => true;
|
||||||
|
|
||||||
protected PlacementBlueprint(HitObject hitObject)
|
protected PlacementBlueprint()
|
||||||
{
|
{
|
||||||
HitObject = hitObject;
|
|
||||||
|
|
||||||
// adding the default hit sample should be the case regardless of the ruleset.
|
|
||||||
HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_NORMAL));
|
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
// This is required to allow the blueprint's position to be updated via OnMouseMove/Handle
|
// This is required to allow the blueprint's position to be updated via OnMouseMove/Handle
|
||||||
@ -78,30 +40,22 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
AlwaysPresent = true;
|
AlwaysPresent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
startTimeBindable = HitObject.StartTimeBindable.GetBoundCopy();
|
|
||||||
startTimeBindable.BindValueChanged(_ => ApplyDefaultsToHitObject(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signals that the placement of <see cref="HitObject"/> has started.
|
/// Signals that the placement has started.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="commitStart">Whether this call is committing a value for HitObject.StartTime and continuing with further adjustments.</param>
|
/// <param name="commitStart">Whether this call is committing a value and continuing with further adjustments.</param>
|
||||||
protected void BeginPlacement(bool commitStart = false)
|
protected virtual void BeginPlacement(bool commitStart = false)
|
||||||
{
|
{
|
||||||
placementHandler.BeginPlacement(HitObject);
|
|
||||||
if (commitStart)
|
if (commitStart)
|
||||||
PlacementActive = PlacementState.Active;
|
PlacementActive = PlacementState.Active;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signals that the placement of <see cref="HitObject"/> has finished.
|
/// Signals that the placement of <see cref="HitObject"/> has finished.
|
||||||
/// This will destroy this <see cref="PlacementBlueprint"/>, and add the HitObject.StartTime to the <see cref="Beatmap"/>.
|
/// This will destroy this <see cref="PlacementBlueprint"/>, and commit the changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="commit">Whether the object should be committed. Note that a commit may fail if <see cref="IsValidForPlacement"/> is <c>false</c>.</param>
|
/// <param name="commit">Whether the changes should be committed. Note that a commit may fail if <see cref="IsValidForPlacement"/> is <c>false</c>.</param>
|
||||||
public void EndPlacement(bool commit)
|
public virtual void EndPlacement(bool commit)
|
||||||
{
|
{
|
||||||
switch (PlacementActive)
|
switch (PlacementActive)
|
||||||
{
|
{
|
||||||
@ -114,10 +68,17 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
placementHandler.EndPlacement(HitObject, IsValidForPlacement && commit);
|
|
||||||
PlacementActive = PlacementState.Finished;
|
PlacementActive = PlacementState.Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the time and position of this <see cref="PlacementBlueprint"/> based on the provided snap information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="result">The snap result information.</param>
|
||||||
|
public virtual void UpdateTimeAndPosition(SnapResult result)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
||||||
{
|
{
|
||||||
if (PlacementActive == PlacementState.Waiting)
|
if (PlacementActive == PlacementState.Waiting)
|
||||||
@ -138,57 +99,6 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the time and position of this <see cref="PlacementBlueprint"/> based on the provided snap information.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="result">The snap result information.</param>
|
|
||||||
public virtual void UpdateTimeAndPosition(SnapResult result)
|
|
||||||
{
|
|
||||||
if (PlacementActive == PlacementState.Waiting)
|
|
||||||
{
|
|
||||||
HitObject.StartTime = result.Time ?? EditorClock.CurrentTime;
|
|
||||||
|
|
||||||
if (HitObject is IHasComboInformation comboInformation)
|
|
||||||
comboInformation.UpdateComboInformation(getPreviousHitObject() as IHasComboInformation);
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastHitObject = getPreviousHitObject();
|
|
||||||
|
|
||||||
if (AutomaticBankAssignment)
|
|
||||||
{
|
|
||||||
// Create samples based on the sample settings of the previous hit object
|
|
||||||
if (lastHitObject != null)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < HitObject.Samples.Count; i++)
|
|
||||||
HitObject.Samples[i] = lastHitObject.CreateHitSampleInfo(HitObject.Samples[i].Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var lastHitNormal = lastHitObject?.Samples?.FirstOrDefault(o => o.Name == HitSampleInfo.HIT_NORMAL);
|
|
||||||
|
|
||||||
if (lastHitNormal != null)
|
|
||||||
{
|
|
||||||
// Only inherit the volume from the previous hit object
|
|
||||||
for (int i = 0; i < HitObject.Samples.Count; i++)
|
|
||||||
HitObject.Samples[i] = HitObject.Samples[i].With(newVolume: lastHitNormal.Volume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HitObject is IHasRepeats hasRepeats)
|
|
||||||
{
|
|
||||||
// Make sure all the node samples are identical to the hit object's samples
|
|
||||||
for (int i = 0; i < hasRepeats.NodeSamples.Count; i++)
|
|
||||||
hasRepeats.NodeSamples[i] = HitObject.Samples.Select(o => o.With()).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invokes <see cref="Objects.HitObject.ApplyDefaults(ControlPointInfo,IBeatmapDifficultyInfo,CancellationToken)"/>,
|
|
||||||
/// refreshing <see cref="Objects.HitObject.NestedHitObjects"/> and parameters for the <see cref="HitObject"/>.
|
|
||||||
/// </summary>
|
|
||||||
protected void ApplyDefaultsToHitObject() => HitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.Difficulty);
|
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
protected override bool Handle(UIEvent e)
|
protected override bool Handle(UIEvent e)
|
||||||
|
@ -6,13 +6,13 @@ using osu.Framework.Localisation;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit.Tools
|
namespace osu.Game.Rulesets.Edit.Tools
|
||||||
{
|
{
|
||||||
public abstract class HitObjectCompositionTool
|
public abstract class CompositionTool
|
||||||
{
|
{
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
|
|
||||||
public LocalisableString TooltipText { get; init; }
|
public LocalisableString TooltipText { get; init; }
|
||||||
|
|
||||||
protected HitObjectCompositionTool(string name)
|
protected CompositionTool(string name)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ using osu.Game.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit.Tools
|
namespace osu.Game.Rulesets.Edit.Tools
|
||||||
{
|
{
|
||||||
public class SelectTool : HitObjectCompositionTool
|
public class SelectTool : CompositionTool
|
||||||
{
|
{
|
||||||
public SelectTool()
|
public SelectTool()
|
||||||
: base("Select")
|
: base("Select")
|
||||||
@ -18,6 +18,6 @@ namespace osu.Game.Rulesets.Edit.Tools
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.EditorSelect };
|
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.EditorSelect };
|
||||||
|
|
||||||
public override PlacementBlueprint CreatePlacementBlueprint() => null;
|
public override HitObjectPlacementBlueprint CreatePlacementBlueprint() => null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
public PlacementBlueprint CurrentPlacement { get; private set; }
|
public PlacementBlueprint CurrentPlacement { get; private set; }
|
||||||
|
|
||||||
|
public HitObjectPlacementBlueprint CurrentHitObjectPlacement => CurrentPlacement as HitObjectPlacementBlueprint;
|
||||||
|
|
||||||
[Resolved(canBeNull: true)]
|
[Resolved(canBeNull: true)]
|
||||||
private EditorScreenWithTimeline editorScreen { get; set; }
|
private EditorScreenWithTimeline editorScreen { get; set; }
|
||||||
|
|
||||||
@ -164,13 +166,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
private void updatePlacementNewCombo()
|
private void updatePlacementNewCombo()
|
||||||
{
|
{
|
||||||
if (CurrentPlacement?.HitObject is IHasComboInformation c)
|
if (CurrentHitObjectPlacement?.HitObject is IHasComboInformation c)
|
||||||
c.NewCombo = NewCombo.Value == TernaryState.True;
|
c.NewCombo = NewCombo.Value == TernaryState.True;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePlacementSamples()
|
private void updatePlacementSamples()
|
||||||
{
|
{
|
||||||
if (CurrentPlacement == null) return;
|
if (CurrentHitObjectPlacement == null) return;
|
||||||
|
|
||||||
foreach (var kvp in SelectionHandler.SelectionSampleStates)
|
foreach (var kvp in SelectionHandler.SelectionSampleStates)
|
||||||
sampleChanged(kvp.Key, kvp.Value.Value);
|
sampleChanged(kvp.Key, kvp.Value.Value);
|
||||||
@ -181,9 +183,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
private void sampleChanged(string sampleName, TernaryState state)
|
private void sampleChanged(string sampleName, TernaryState state)
|
||||||
{
|
{
|
||||||
if (CurrentPlacement == null) return;
|
if (CurrentHitObjectPlacement == null) return;
|
||||||
|
|
||||||
var samples = CurrentPlacement.HitObject.Samples;
|
var samples = CurrentHitObjectPlacement.HitObject.Samples;
|
||||||
|
|
||||||
var existingSample = samples.FirstOrDefault(s => s.Name == sampleName);
|
var existingSample = samples.FirstOrDefault(s => s.Name == sampleName);
|
||||||
|
|
||||||
@ -196,19 +198,19 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
case TernaryState.True:
|
case TernaryState.True:
|
||||||
if (existingSample == null)
|
if (existingSample == null)
|
||||||
samples.Add(CurrentPlacement.HitObject.CreateHitSampleInfo(sampleName));
|
samples.Add(CurrentHitObjectPlacement.HitObject.CreateHitSampleInfo(sampleName));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bankChanged(string bankName, TernaryState state)
|
private void bankChanged(string bankName, TernaryState state)
|
||||||
{
|
{
|
||||||
if (CurrentPlacement == null) return;
|
if (CurrentHitObjectPlacement == null) return;
|
||||||
|
|
||||||
if (bankName == EditorSelectionHandler.HIT_BANK_AUTO)
|
if (bankName == EditorSelectionHandler.HIT_BANK_AUTO)
|
||||||
CurrentPlacement.AutomaticBankAssignment = state == TernaryState.True;
|
CurrentHitObjectPlacement.AutomaticBankAssignment = state == TernaryState.True;
|
||||||
else if (state == TernaryState.True)
|
else if (state == TernaryState.True)
|
||||||
CurrentPlacement.HitObject.Samples = CurrentPlacement.HitObject.Samples.Select(s => s.With(newBank: bankName)).ToList();
|
CurrentHitObjectPlacement.HitObject.Samples = CurrentHitObjectPlacement.HitObject.Samples.Select(s => s.With(newBank: bankName)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly Bindable<TernaryState> NewCombo = new Bindable<TernaryState> { Description = "New Combo" };
|
public readonly Bindable<TernaryState> NewCombo = new Bindable<TernaryState> { Description = "New Combo" };
|
||||||
@ -386,12 +388,12 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
CurrentPlacement = null;
|
CurrentPlacement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HitObjectCompositionTool currentTool;
|
private CompositionTool currentTool;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current placement tool.
|
/// The current placement tool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public HitObjectCompositionTool CurrentTool
|
public CompositionTool CurrentTool
|
||||||
{
|
{
|
||||||
get => currentTool;
|
get => currentTool;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
public abstract partial class PlacementBlueprintTestScene : OsuManualInputManagerTestScene, IPlacementHandler
|
public abstract partial class PlacementBlueprintTestScene : OsuManualInputManagerTestScene, IPlacementHandler
|
||||||
{
|
{
|
||||||
protected readonly Container HitObjectContainer;
|
protected readonly Container HitObjectContainer;
|
||||||
protected PlacementBlueprint CurrentBlueprint { get; private set; }
|
protected HitObjectPlacementBlueprint CurrentBlueprint { get; private set; }
|
||||||
|
|
||||||
protected PlacementBlueprintTestScene()
|
protected PlacementBlueprintTestScene()
|
||||||
{
|
{
|
||||||
@ -87,14 +87,14 @@ namespace osu.Game.Tests.Visual
|
|||||||
CurrentBlueprint.UpdateTimeAndPosition(SnapForBlueprint(CurrentBlueprint));
|
CurrentBlueprint.UpdateTimeAndPosition(SnapForBlueprint(CurrentBlueprint));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual SnapResult SnapForBlueprint(PlacementBlueprint blueprint) =>
|
protected virtual SnapResult SnapForBlueprint(HitObjectPlacementBlueprint blueprint) =>
|
||||||
new SnapResult(InputManager.CurrentState.Mouse.Position, null);
|
new SnapResult(InputManager.CurrentState.Mouse.Position, null);
|
||||||
|
|
||||||
public override void Add(Drawable drawable)
|
public override void Add(Drawable drawable)
|
||||||
{
|
{
|
||||||
base.Add(drawable);
|
base.Add(drawable);
|
||||||
|
|
||||||
if (drawable is PlacementBlueprint blueprint)
|
if (drawable is HitObjectPlacementBlueprint blueprint)
|
||||||
{
|
{
|
||||||
blueprint.Show();
|
blueprint.Show();
|
||||||
blueprint.UpdateTimeAndPosition(SnapForBlueprint(blueprint));
|
blueprint.UpdateTimeAndPosition(SnapForBlueprint(blueprint));
|
||||||
@ -106,6 +106,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
protected virtual Container CreateHitObjectContainer() => new Container { RelativeSizeAxes = Axes.Both };
|
protected virtual Container CreateHitObjectContainer() => new Container { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
protected abstract DrawableHitObject CreateHitObject(HitObject hitObject);
|
protected abstract DrawableHitObject CreateHitObject(HitObject hitObject);
|
||||||
protected abstract PlacementBlueprint CreateBlueprint();
|
protected abstract HitObjectPlacementBlueprint CreateBlueprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user