mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 03:22:55 +08:00
Merge remote-tracking branch 'upstream/master' into add-legacy-default
This commit is contained in:
commit
d17cfe20c2
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
public class CatchRuleset : Ruleset
|
||||
{
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableCatchRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableCatchRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
|
||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
|
||||
|
||||
|
@ -25,11 +25,11 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
protected override bool UserScrollSpeedAdjustment => false;
|
||||
|
||||
public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableCatchRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
Direction.Value = ScrollingDirection.Down;
|
||||
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
|
||||
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.Beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
|
||||
}
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);
|
||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
public new IScrollingInfo ScrollingInfo => base.ScrollingInfo;
|
||||
|
||||
public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableManiaEditRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
[Cached(Type = typeof(IManiaHitObjectComposer))]
|
||||
public class ManiaHitObjectComposer : HitObjectComposer<ManiaHitObject>, IManiaHitObjectComposer
|
||||
{
|
||||
protected new DrawableManiaEditRuleset DrawableRuleset { get; private set; }
|
||||
private DrawableManiaEditRuleset drawableRuleset;
|
||||
|
||||
public ManiaHitObjectComposer(Ruleset ruleset)
|
||||
: base(ruleset)
|
||||
@ -33,23 +33,23 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
/// </summary>
|
||||
/// <param name="screenSpacePosition">The screen-space position.</param>
|
||||
/// <returns>The column which intersects with <paramref name="screenSpacePosition"/>.</returns>
|
||||
public Column ColumnAt(Vector2 screenSpacePosition) => DrawableRuleset.GetColumnByPosition(screenSpacePosition);
|
||||
public Column ColumnAt(Vector2 screenSpacePosition) => drawableRuleset.GetColumnByPosition(screenSpacePosition);
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
public int TotalColumns => ((ManiaPlayfield)DrawableRuleset.Playfield).TotalColumns;
|
||||
public int TotalColumns => ((ManiaPlayfield)drawableRuleset.Playfield).TotalColumns;
|
||||
|
||||
protected override DrawableRuleset<ManiaHitObject> CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
protected override DrawableRuleset<ManiaHitObject> CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
{
|
||||
DrawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods);
|
||||
drawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods);
|
||||
|
||||
// This is the earliest we can cache the scrolling info to ourselves, before masks are added to the hierarchy and inject it
|
||||
dependencies.CacheAs(DrawableRuleset.ScrollingInfo);
|
||||
dependencies.CacheAs(drawableRuleset.ScrollingInfo);
|
||||
|
||||
return DrawableRuleset;
|
||||
return drawableRuleset;
|
||||
}
|
||||
|
||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
public class ManiaRuleset : Ruleset
|
||||
{
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableManiaRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableManiaRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
|
||||
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score);
|
||||
|
||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
private readonly Bindable<ManiaScrollingDirection> configDirection = new Bindable<ManiaScrollingDirection>();
|
||||
|
||||
public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableManiaRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
// Generate the bar lines
|
||||
|
@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
public class DrawableOsuEditRuleset : DrawableOsuRuleset
|
||||
{
|
||||
public DrawableOsuEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableOsuEditRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
}
|
||||
|
||||
protected override DrawableRuleset<OsuHitObject> CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
protected override DrawableRuleset<OsuHitObject> CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
=> new DrawableOsuEditRuleset(ruleset, beatmap, mods);
|
||||
|
||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
{
|
||||
public class OsuRuleset : Ruleset
|
||||
{
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableOsuRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableOsuRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap);
|
||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap);
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
{
|
||||
protected new OsuRulesetConfigManager Config => (OsuRulesetConfigManager)base.Config;
|
||||
|
||||
public DrawableOsuRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableOsuRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
public class TaikoRuleset : Ruleset
|
||||
{
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableTaikoRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableTaikoRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap);
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
|
||||
protected override bool UserScrollSpeedAdjustment => false;
|
||||
|
||||
public DrawableTaikoRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public DrawableTaikoRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
Direction.Value = ScrollingDirection.Left;
|
||||
|
@ -16,15 +16,13 @@ using osu.Game.Rulesets.Osu.Edit;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Screens.Edit.Compose;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
[Cached(Type = typeof(IPlacementHandler))]
|
||||
public class TestSceneHitObjectComposer : OsuTestScene, IPlacementHandler
|
||||
public class TestSceneHitObjectComposer : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
@ -39,8 +37,6 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
typeof(HitCirclePlacementBlueprint),
|
||||
};
|
||||
|
||||
private HitObjectComposer composer;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@ -67,15 +63,7 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
Dependencies.CacheAs<IAdjustableClock>(clock);
|
||||
Dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||
|
||||
Child = composer = new OsuHitObjectComposer(new OsuRuleset());
|
||||
Child = new OsuHitObjectComposer(new OsuRuleset());
|
||||
}
|
||||
|
||||
public void BeginPlacement(HitObject hitObject)
|
||||
{
|
||||
}
|
||||
|
||||
public void EndPlacement(HitObject hitObject) => composer.Add(hitObject);
|
||||
|
||||
public void Delete(HitObject hitObject) => composer.Remove(hitObject);
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => throw new NotImplementedException();
|
||||
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new TestDrawableScrollingRuleset(this, beatmap, mods);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new TestDrawableScrollingRuleset(this, beatmap, mods);
|
||||
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap);
|
||||
|
||||
@ -193,7 +193,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Overlapping;
|
||||
|
||||
public TestDrawableScrollingRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public TestDrawableScrollingRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
TimeRange.Value = time_range;
|
||||
|
@ -14,7 +14,7 @@ namespace osu.Game.Beatmaps
|
||||
/// <summary>
|
||||
/// A Beatmap containing converted HitObjects.
|
||||
/// </summary>
|
||||
public class Beatmap<T> : IBeatmap
|
||||
public class Beatmap<T> : IBeatmap<T>
|
||||
where T : HitObject
|
||||
{
|
||||
public BeatmapInfo BeatmapInfo { get; set; } = new BeatmapInfo
|
||||
@ -36,17 +36,13 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
public List<BreakPeriod> Breaks { get; set; } = new List<BreakPeriod>();
|
||||
|
||||
/// <summary>
|
||||
/// Total amount of break time in the beatmap.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public double TotalBreakTime => Breaks.Sum(b => b.Duration);
|
||||
|
||||
/// <summary>
|
||||
/// The HitObjects this Beatmap contains.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(TypedListConverter<HitObject>))]
|
||||
public List<T> HitObjects = new List<T>();
|
||||
public List<T> HitObjects { get; set; } = new List<T>();
|
||||
|
||||
IReadOnlyList<T> IBeatmap<T>.HitObjects => HitObjects;
|
||||
|
||||
IReadOnlyList<HitObject> IBeatmap.HitObjects => HitObjects;
|
||||
|
||||
|
@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => new Mod[] { };
|
||||
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -53,4 +53,13 @@ namespace osu.Game.Beatmaps
|
||||
/// <returns>The shallow-cloned beatmap.</returns>
|
||||
IBeatmap Clone();
|
||||
}
|
||||
|
||||
public interface IBeatmap<out T> : IBeatmap
|
||||
where T : HitObject
|
||||
{
|
||||
/// <summary>
|
||||
/// The hitobjects contained by this beatmap.
|
||||
/// </summary>
|
||||
new IReadOnlyList<T> HitObjects { get; }
|
||||
}
|
||||
}
|
||||
|
61
osu.Game/Beatmaps/IWorkingBeatmap.cs
Normal file
61
osu.Game/Beatmaps/IWorkingBeatmap.cs
Normal file
@ -0,0 +1,61 @@
|
||||
// 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.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
public interface IWorkingBeatmap
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves the <see cref="IBeatmap"/> which this <see cref="WorkingBeatmap"/> represents.
|
||||
/// </summary>
|
||||
IBeatmap Beatmap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the background for this <see cref="WorkingBeatmap"/>.
|
||||
/// </summary>
|
||||
Texture Background { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the audio track for this <see cref="WorkingBeatmap"/>.
|
||||
/// </summary>
|
||||
Track Track { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the <see cref="Waveform"/> for the <see cref="Track"/> of this <see cref="WorkingBeatmap"/>.
|
||||
/// </summary>
|
||||
Waveform Waveform { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the <see cref="Storyboard"/> which this <see cref="WorkingBeatmap"/> provides.
|
||||
/// </summary>
|
||||
Storyboard Storyboard { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the <see cref="Skin"/> which this <see cref="WorkingBeatmap"/> provides.
|
||||
/// </summary>
|
||||
Skin Skin { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a playable <see cref="IBeatmap"/> from <see cref="Beatmap"/> using the applicable converters for a specific <see cref="RulesetInfo"/>.
|
||||
/// <para>
|
||||
/// The returned <see cref="IBeatmap"/> is in a playable state - all <see cref="HitObject"/> and <see cref="BeatmapDifficulty"/> <see cref="Mod"/>s
|
||||
/// have been applied, and <see cref="HitObject"/>s have been fully constructed.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param>
|
||||
/// <returns>The converted <see cref="IBeatmap"/>.</returns>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
|
||||
IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods);
|
||||
}
|
||||
}
|
@ -16,14 +16,13 @@ using osu.Framework.Audio;
|
||||
using osu.Framework.Statistics;
|
||||
using osu.Game.IO.Serialization;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
public abstract class WorkingBeatmap : IDisposable
|
||||
public abstract class WorkingBeatmap : IWorkingBeatmap, IDisposable
|
||||
{
|
||||
public readonly BeatmapInfo BeatmapInfo;
|
||||
|
||||
@ -97,17 +96,6 @@ namespace osu.Game.Beatmaps
|
||||
/// <returns>The applicable <see cref="IBeatmapConverter"/>.</returns>
|
||||
protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap);
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a playable <see cref="IBeatmap"/> from <see cref="Beatmap"/> using the applicable converters for a specific <see cref="RulesetInfo"/>.
|
||||
/// <para>
|
||||
/// The returned <see cref="IBeatmap"/> is in a playable state - all <see cref="HitObject"/> and <see cref="BeatmapDifficulty"/> <see cref="Mod"/>s
|
||||
/// have been applied, and <see cref="HitObject"/>s have been fully constructed.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param>
|
||||
/// <returns>The converted <see cref="IBeatmap"/>.</returns>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
|
||||
public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods)
|
||||
{
|
||||
var rulesetInstance = ruleset.CreateInstance();
|
||||
|
@ -1,116 +0,0 @@
|
||||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
public abstract class DrawableEditRuleset : CompositeDrawable
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="Playfield"/> contained by this <see cref="DrawableEditRuleset"/>.
|
||||
/// </summary>
|
||||
public abstract Playfield Playfield { get; }
|
||||
|
||||
public abstract PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer();
|
||||
|
||||
internal DrawableEditRuleset()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="HitObject"/> to the <see cref="Beatmap"/> and displays a visual representation of it.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> to add.</param>
|
||||
/// <returns>The visual representation of <paramref name="hitObject"/>.</returns>
|
||||
internal abstract DrawableHitObject Add(HitObject hitObject);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a <see cref="HitObject"/> from the <see cref="Beatmap"/> and the display.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> to remove.</param>
|
||||
/// <returns>The visual representation of the removed <paramref name="hitObject"/>.</returns>
|
||||
internal abstract DrawableHitObject Remove(HitObject hitObject);
|
||||
}
|
||||
|
||||
public class DrawableEditRuleset<TObject> : DrawableEditRuleset
|
||||
where TObject : HitObject
|
||||
{
|
||||
public override Playfield Playfield => drawableRuleset.Playfield;
|
||||
|
||||
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => drawableRuleset.CreatePlayfieldAdjustmentContainer();
|
||||
|
||||
private Ruleset ruleset => drawableRuleset.Ruleset;
|
||||
private Beatmap<TObject> beatmap => drawableRuleset.Beatmap;
|
||||
|
||||
private readonly DrawableRuleset<TObject> drawableRuleset;
|
||||
|
||||
public DrawableEditRuleset(DrawableRuleset<TObject> drawableRuleset)
|
||||
{
|
||||
this.drawableRuleset = drawableRuleset;
|
||||
|
||||
InternalChild = drawableRuleset;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
drawableRuleset.FrameStablePlayback = false;
|
||||
Playfield.DisplayJudgements.Value = false;
|
||||
}
|
||||
|
||||
internal override DrawableHitObject Add(HitObject hitObject)
|
||||
{
|
||||
var tObject = (TObject)hitObject;
|
||||
|
||||
// Add to beatmap, preserving sorting order
|
||||
var insertionIndex = beatmap.HitObjects.FindLastIndex(h => h.StartTime <= hitObject.StartTime);
|
||||
beatmap.HitObjects.Insert(insertionIndex + 1, tObject);
|
||||
|
||||
// Process object
|
||||
var processor = ruleset.CreateBeatmapProcessor(beatmap);
|
||||
|
||||
processor?.PreProcess();
|
||||
tObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
|
||||
processor?.PostProcess();
|
||||
|
||||
// Add visual representation
|
||||
var drawableObject = drawableRuleset.CreateDrawableRepresentation(tObject);
|
||||
|
||||
drawableRuleset.Playfield.Add(drawableObject);
|
||||
drawableRuleset.Playfield.PostProcess();
|
||||
|
||||
return drawableObject;
|
||||
}
|
||||
|
||||
internal override DrawableHitObject Remove(HitObject hitObject)
|
||||
{
|
||||
var tObject = (TObject)hitObject;
|
||||
|
||||
// Remove from beatmap
|
||||
beatmap.HitObjects.Remove(tObject);
|
||||
|
||||
// Process the beatmap
|
||||
var processor = ruleset.CreateBeatmapProcessor(beatmap);
|
||||
|
||||
processor?.PreProcess();
|
||||
processor?.PostProcess();
|
||||
|
||||
// Remove visual representation
|
||||
var drawableObject = Playfield.AllHitObjects.Single(d => d.HitObject == hitObject);
|
||||
|
||||
drawableRuleset.Playfield.Remove(drawableObject);
|
||||
drawableRuleset.Playfield.PostProcess();
|
||||
|
||||
return drawableObject;
|
||||
}
|
||||
}
|
||||
}
|
80
osu.Game/Rulesets/Edit/DrawableEditRulesetWrapper.cs
Normal file
80
osu.Game/Rulesets/Edit/DrawableEditRulesetWrapper.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.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Edit;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
/// <summary>
|
||||
/// A wrapper for a <see cref="DrawableRuleset{TObject}"/>. Handles adding visual representations of <see cref="HitObject"/>s to the underlying <see cref="DrawableRuleset{TObject}"/>.
|
||||
/// </summary>
|
||||
internal class DrawableEditRulesetWrapper<TObject> : CompositeDrawable
|
||||
where TObject : HitObject
|
||||
{
|
||||
public Playfield Playfield => drawableRuleset.Playfield;
|
||||
|
||||
private readonly DrawableRuleset<TObject> drawableRuleset;
|
||||
|
||||
[Resolved]
|
||||
private IEditorBeatmap<TObject> beatmap { get; set; }
|
||||
|
||||
public DrawableEditRulesetWrapper(DrawableRuleset<TObject> drawableRuleset)
|
||||
{
|
||||
this.drawableRuleset = drawableRuleset;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
InternalChild = drawableRuleset;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
drawableRuleset.FrameStablePlayback = false;
|
||||
Playfield.DisplayJudgements.Value = false;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
beatmap.HitObjectAdded += addHitObject;
|
||||
beatmap.HitObjectRemoved += removeHitObject;
|
||||
}
|
||||
|
||||
private void addHitObject(HitObject hitObject)
|
||||
{
|
||||
var drawableObject = drawableRuleset.CreateDrawableRepresentation((TObject)hitObject);
|
||||
|
||||
drawableRuleset.Playfield.Add(drawableObject);
|
||||
drawableRuleset.Playfield.PostProcess();
|
||||
}
|
||||
|
||||
private void removeHitObject(HitObject hitObject)
|
||||
{
|
||||
var drawableObject = Playfield.AllHitObjects.Single(d => d.HitObject == hitObject);
|
||||
|
||||
drawableRuleset.Playfield.Remove(drawableObject);
|
||||
drawableRuleset.Playfield.PostProcess();
|
||||
}
|
||||
|
||||
public PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => drawableRuleset.CreatePlayfieldAdjustmentContainer();
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (beatmap != null)
|
||||
{
|
||||
beatmap.HitObjectAdded -= addHitObject;
|
||||
beatmap.HitObjectRemoved -= removeHitObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,45 +18,47 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Components.RadioButtons;
|
||||
using osu.Game.Screens.Edit.Compose;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
public abstract class HitObjectComposer : CompositeDrawable
|
||||
[Cached(Type = typeof(IPlacementHandler))]
|
||||
public abstract class HitObjectComposer<TObject> : HitObjectComposer, IPlacementHandler
|
||||
where TObject : HitObject
|
||||
{
|
||||
public IEnumerable<DrawableHitObject> HitObjects => DrawableRuleset.Playfield.AllHitObjects;
|
||||
protected IRulesetConfigManager Config { get; private set; }
|
||||
|
||||
protected readonly Ruleset Ruleset;
|
||||
|
||||
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
protected IRulesetConfigManager Config { get; private set; }
|
||||
|
||||
private readonly List<Container> layerContainers = new List<Container>();
|
||||
|
||||
protected DrawableEditRuleset DrawableRuleset { get; private set; }
|
||||
private IWorkingBeatmap workingBeatmap;
|
||||
private Beatmap<TObject> playableBeatmap;
|
||||
private EditorBeatmap<TObject> editorBeatmap;
|
||||
private IBeatmapProcessor beatmapProcessor;
|
||||
|
||||
private DrawableEditRulesetWrapper<TObject> drawableRulesetWrapper;
|
||||
private BlueprintContainer blueprintContainer;
|
||||
private readonly List<Container> layerContainers = new List<Container>();
|
||||
|
||||
private InputManager inputManager;
|
||||
|
||||
internal HitObjectComposer(Ruleset ruleset)
|
||||
protected HitObjectComposer(Ruleset ruleset)
|
||||
{
|
||||
Ruleset = ruleset;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IBindable<WorkingBeatmap> beatmap, IFrameBasedClock framedClock)
|
||||
private void load(IFrameBasedClock framedClock)
|
||||
{
|
||||
Beatmap.BindTo(beatmap);
|
||||
|
||||
try
|
||||
{
|
||||
DrawableRuleset = CreateDrawableRuleset();
|
||||
DrawableRuleset.Clock = framedClock;
|
||||
drawableRulesetWrapper = new DrawableEditRulesetWrapper<TObject>(CreateDrawableRuleset(Ruleset, workingBeatmap, Array.Empty<Mod>()))
|
||||
{
|
||||
Clock = framedClock
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -64,10 +66,10 @@ namespace osu.Game.Rulesets.Edit
|
||||
return;
|
||||
}
|
||||
|
||||
var layerBelowRuleset = DrawableRuleset.CreatePlayfieldAdjustmentContainer();
|
||||
var layerBelowRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer();
|
||||
layerBelowRuleset.Child = new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
var layerAboveRuleset = DrawableRuleset.CreatePlayfieldAdjustmentContainer();
|
||||
var layerAboveRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer();
|
||||
layerAboveRuleset.Child = blueprintContainer = new BlueprintContainer();
|
||||
|
||||
layerContainers.Add(layerBelowRuleset);
|
||||
@ -98,7 +100,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
Children = new Drawable[]
|
||||
{
|
||||
layerBelowRuleset,
|
||||
DrawableRuleset,
|
||||
drawableRulesetWrapper,
|
||||
layerAboveRuleset
|
||||
}
|
||||
}
|
||||
@ -118,6 +120,28 @@ namespace osu.Game.Rulesets.Edit
|
||||
toolboxCollection.Items[0].Select();
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var parentWorkingBeatmap = parent.Get<IBindable<WorkingBeatmap>>().Value;
|
||||
|
||||
playableBeatmap = (Beatmap<TObject>)parentWorkingBeatmap.GetPlayableBeatmap(Ruleset.RulesetInfo, Array.Empty<Mod>());
|
||||
workingBeatmap = new EditorWorkingBeatmap<TObject>(playableBeatmap, parentWorkingBeatmap);
|
||||
|
||||
beatmapProcessor = Ruleset.CreateBeatmapProcessor(playableBeatmap);
|
||||
|
||||
editorBeatmap = new EditorBeatmap<TObject>(playableBeatmap);
|
||||
editorBeatmap.HitObjectAdded += addHitObject;
|
||||
editorBeatmap.HitObjectRemoved += removeHitObject;
|
||||
|
||||
var dependencies = new DependencyContainer(parent);
|
||||
dependencies.CacheAs<IEditorBeatmap>(editorBeatmap);
|
||||
dependencies.CacheAs<IEditorBeatmap<TObject>>(editorBeatmap);
|
||||
|
||||
Config = dependencies.Get<RulesetConfigCache>().GetConfigFor(Ruleset);
|
||||
|
||||
return base.CreateChildDependencies(dependencies);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
@ -125,45 +149,76 @@ namespace osu.Game.Rulesets.Edit
|
||||
inputManager = GetContainingInputManager();
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
dependencies.CacheAs(this);
|
||||
Config = dependencies.Get<RulesetConfigCache>().GetConfigFor(Ruleset);
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
layerContainers.ForEach(l =>
|
||||
{
|
||||
l.Anchor = DrawableRuleset.Playfield.Anchor;
|
||||
l.Origin = DrawableRuleset.Playfield.Origin;
|
||||
l.Position = DrawableRuleset.Playfield.Position;
|
||||
l.Size = DrawableRuleset.Playfield.Size;
|
||||
l.Anchor = drawableRulesetWrapper.Playfield.Anchor;
|
||||
l.Origin = drawableRulesetWrapper.Playfield.Origin;
|
||||
l.Position = drawableRulesetWrapper.Playfield.Position;
|
||||
l.Size = drawableRulesetWrapper.Playfield.Size;
|
||||
});
|
||||
}
|
||||
|
||||
private void addHitObject(HitObject hitObject)
|
||||
{
|
||||
beatmapProcessor?.PreProcess();
|
||||
hitObject.ApplyDefaults(playableBeatmap.ControlPointInfo, playableBeatmap.BeatmapInfo.BaseDifficulty);
|
||||
beatmapProcessor?.PostProcess();
|
||||
}
|
||||
|
||||
private void removeHitObject(HitObject hitObject)
|
||||
{
|
||||
beatmapProcessor?.PreProcess();
|
||||
beatmapProcessor?.PostProcess();
|
||||
}
|
||||
|
||||
public override IEnumerable<DrawableHitObject> HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects;
|
||||
public override bool CursorInPlacementArea => drawableRulesetWrapper.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
|
||||
|
||||
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
||||
|
||||
protected abstract DrawableRuleset<TObject> CreateDrawableRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods);
|
||||
|
||||
public void BeginPlacement(HitObject hitObject)
|
||||
{
|
||||
}
|
||||
|
||||
public void EndPlacement(HitObject hitObject) => editorBeatmap.Add(hitObject);
|
||||
|
||||
public void Delete(HitObject hitObject) => editorBeatmap.Remove(hitObject);
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (editorBeatmap != null)
|
||||
{
|
||||
editorBeatmap.HitObjectAdded -= addHitObject;
|
||||
editorBeatmap.HitObjectRemoved -= removeHitObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Cached(typeof(HitObjectComposer))]
|
||||
public abstract class HitObjectComposer : CompositeDrawable
|
||||
{
|
||||
internal HitObjectComposer()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// All the <see cref="DrawableHitObject"/>s.
|
||||
/// </summary>
|
||||
public abstract IEnumerable<DrawableHitObject> HitObjects { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the user's cursor is currently in an area of the <see cref="HitObjectComposer"/> that is valid for placement.
|
||||
/// </summary>
|
||||
public virtual bool CursorInPlacementArea => DrawableRuleset.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="HitObject"/> to the <see cref="Beatmaps.Beatmap"/> and visualises it.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> to add.</param>
|
||||
public void Add(HitObject hitObject) => blueprintContainer.AddBlueprintFor(DrawableRuleset.Add(hitObject));
|
||||
|
||||
public void Remove(HitObject hitObject) => blueprintContainer.RemoveBlueprintFor(DrawableRuleset.Remove(hitObject));
|
||||
|
||||
internal abstract DrawableEditRuleset CreateDrawableRuleset();
|
||||
|
||||
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
||||
public abstract bool CursorInPlacementArea { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="SelectionBlueprint"/> for a specific <see cref="DrawableHitObject"/>.
|
||||
@ -176,18 +231,4 @@ namespace osu.Game.Rulesets.Edit
|
||||
/// </summary>
|
||||
public virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler();
|
||||
}
|
||||
|
||||
public abstract class HitObjectComposer<TObject> : HitObjectComposer
|
||||
where TObject : HitObject
|
||||
{
|
||||
protected HitObjectComposer(Ruleset ruleset)
|
||||
: base(ruleset)
|
||||
{
|
||||
}
|
||||
|
||||
internal override DrawableEditRuleset CreateDrawableRuleset()
|
||||
=> new DrawableEditRuleset<TObject>(CreateDrawableRuleset(Ruleset, Beatmap.Value, Array.Empty<Mod>()));
|
||||
|
||||
protected abstract DrawableRuleset<TObject> CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ namespace osu.Game.Rulesets
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply.</param>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">Unable to successfully load the beatmap to be usable with this ruleset.</exception>
|
||||
/// <returns></returns>
|
||||
public abstract DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods);
|
||||
public abstract DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="IBeatmapConverter"/> to convert a <see cref="IBeatmap"/> to one that is applicable for this <see cref="Ruleset"/>.
|
||||
|
@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.UI
|
||||
/// <param name="ruleset">The ruleset being represented.</param>
|
||||
/// <param name="workingBeatmap">The beatmap to create the hit renderer for.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply.</param>
|
||||
protected DrawableRuleset(Ruleset ruleset, WorkingBeatmap workingBeatmap, IReadOnlyList<Mod> mods)
|
||||
protected DrawableRuleset(Ruleset ruleset, IWorkingBeatmap workingBeatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset)
|
||||
{
|
||||
if (workingBeatmap == null)
|
||||
|
@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
[Cached(Type = typeof(IScrollingInfo))]
|
||||
private readonly LocalScrollingInfo scrollingInfo;
|
||||
|
||||
protected DrawableScrollingRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
protected DrawableScrollingRuleset(Ruleset ruleset, IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
scrollingInfo = new LocalScrollingInfo();
|
||||
|
@ -11,6 +11,7 @@ using osu.Framework.Input.Events;
|
||||
using osu.Framework.Input.States;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Edit.Tools;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Compose.Components
|
||||
@ -29,6 +30,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
[Resolved]
|
||||
private HitObjectComposer composer { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IEditorBeatmap beatmap { get; set; }
|
||||
|
||||
public BlueprintContainer()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
@ -53,7 +57,15 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
};
|
||||
|
||||
foreach (var obj in composer.HitObjects)
|
||||
AddBlueprintFor(obj);
|
||||
addBlueprintFor(obj);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
beatmap.HitObjectAdded += addBlueprintFor;
|
||||
beatmap.HitObjectRemoved += removeBlueprintFor;
|
||||
}
|
||||
|
||||
private HitObjectCompositionTool currentTool;
|
||||
@ -75,11 +87,32 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a blueprint for a <see cref="DrawableHitObject"/> which adds movement support.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to create a blueprint for.</param>
|
||||
public void AddBlueprintFor(DrawableHitObject hitObject)
|
||||
private void addBlueprintFor(HitObject hitObject)
|
||||
{
|
||||
var drawable = composer.HitObjects.FirstOrDefault(d => d.HitObject == hitObject);
|
||||
if (drawable == null)
|
||||
return;
|
||||
|
||||
addBlueprintFor(drawable);
|
||||
}
|
||||
|
||||
private void removeBlueprintFor(HitObject hitObject)
|
||||
{
|
||||
var blueprint = selectionBlueprints.Single(m => m.HitObject.HitObject == hitObject);
|
||||
if (blueprint == null)
|
||||
return;
|
||||
|
||||
blueprint.Deselect();
|
||||
|
||||
blueprint.Selected -= onBlueprintSelected;
|
||||
blueprint.Deselected -= onBlueprintDeselected;
|
||||
blueprint.SelectionRequested -= onSelectionRequested;
|
||||
blueprint.DragRequested -= onDragRequested;
|
||||
|
||||
selectionBlueprints.Remove(blueprint);
|
||||
}
|
||||
|
||||
private void addBlueprintFor(DrawableHitObject hitObject)
|
||||
{
|
||||
refreshTool();
|
||||
|
||||
@ -95,25 +128,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
selectionBlueprints.Add(blueprint);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a blueprint for a <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="DrawableHitObject"/> for which to remove the blueprint.</param>
|
||||
public void RemoveBlueprintFor(DrawableHitObject hitObject)
|
||||
{
|
||||
var blueprint = selectionBlueprints.Single(m => m.HitObject == hitObject);
|
||||
if (blueprint == null)
|
||||
return;
|
||||
|
||||
blueprint.Deselect();
|
||||
|
||||
blueprint.Selected -= onBlueprintSelected;
|
||||
blueprint.Deselected -= onBlueprintDeselected;
|
||||
blueprint.SelectionRequested -= onSelectionRequested;
|
||||
blueprint.DragRequested -= onDragRequested;
|
||||
|
||||
selectionBlueprints.Remove(blueprint);
|
||||
}
|
||||
private void removeBlueprintFor(DrawableHitObject hitObject) => removeBlueprintFor(hitObject.HitObject);
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
@ -183,6 +198,17 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
|
||||
private void onDragRequested(SelectionBlueprint blueprint, DragEvent dragEvent) => selectionHandler.HandleDrag(blueprint, dragEvent);
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (beatmap != null)
|
||||
{
|
||||
beatmap.HitObjectAdded -= addBlueprintFor;
|
||||
beatmap.HitObjectRemoved -= removeBlueprintFor;
|
||||
}
|
||||
}
|
||||
|
||||
private class SelectionBlueprintContainer : Container<SelectionBlueprint>
|
||||
{
|
||||
protected override int Compare(Drawable x, Drawable y)
|
||||
|
@ -9,15 +9,13 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Compose
|
||||
{
|
||||
[Cached(Type = typeof(IPlacementHandler))]
|
||||
public class ComposeScreen : EditorScreen, IPlacementHandler
|
||||
public class ComposeScreen : EditorScreen
|
||||
{
|
||||
private const float vertical_margins = 10;
|
||||
private const float horizontal_margins = 20;
|
||||
@ -119,13 +117,5 @@ namespace osu.Game.Screens.Edit.Compose
|
||||
|
||||
composerContainer.Child = composer;
|
||||
}
|
||||
|
||||
public void BeginPlacement(HitObject hitObject)
|
||||
{
|
||||
}
|
||||
|
||||
public void EndPlacement(HitObject hitObject) => composer.Add(hitObject);
|
||||
|
||||
public void Delete(HitObject hitObject) => composer.Remove(hitObject);
|
||||
}
|
||||
}
|
||||
|
83
osu.Game/Screens/Edit/EditorBeatmap.cs
Normal file
83
osu.Game/Screens/Edit/EditorBeatmap.cs
Normal file
@ -0,0 +1,83 @@
|
||||
// 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 osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
public class EditorBeatmap<T> : IEditorBeatmap<T>
|
||||
where T : HitObject
|
||||
{
|
||||
public event Action<HitObject> HitObjectAdded;
|
||||
public event Action<HitObject> HitObjectRemoved;
|
||||
|
||||
private readonly Beatmap<T> beatmap;
|
||||
|
||||
public EditorBeatmap(Beatmap<T> beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
public BeatmapInfo BeatmapInfo
|
||||
{
|
||||
get => beatmap.BeatmapInfo;
|
||||
set => beatmap.BeatmapInfo = value;
|
||||
}
|
||||
|
||||
public BeatmapMetadata Metadata => beatmap.Metadata;
|
||||
|
||||
public ControlPointInfo ControlPointInfo => beatmap.ControlPointInfo;
|
||||
|
||||
public List<BreakPeriod> Breaks => beatmap.Breaks;
|
||||
|
||||
public double TotalBreakTime => beatmap.TotalBreakTime;
|
||||
|
||||
IReadOnlyList<T> IBeatmap<T>.HitObjects => beatmap.HitObjects;
|
||||
|
||||
IReadOnlyList<HitObject> IBeatmap.HitObjects => beatmap.HitObjects;
|
||||
|
||||
public IEnumerable<BeatmapStatistic> GetStatistics() => beatmap.GetStatistics();
|
||||
|
||||
public IBeatmap Clone() => (EditorBeatmap<T>)MemberwiseClone();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="HitObject"/> to this <see cref="EditorBeatmap{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> to add.</param>
|
||||
public void Add(T hitObject)
|
||||
{
|
||||
// Preserve existing sorting order in the beatmap
|
||||
var insertionIndex = beatmap.HitObjects.FindLastIndex(h => h.StartTime <= hitObject.StartTime);
|
||||
beatmap.HitObjects.Insert(insertionIndex + 1, hitObject);
|
||||
|
||||
HitObjectAdded?.Invoke(hitObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a <see cref="HitObject"/> from this <see cref="EditorBeatmap{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> to add.</param>
|
||||
public void Remove(T hitObject)
|
||||
{
|
||||
if (beatmap.HitObjects.Remove(hitObject))
|
||||
HitObjectRemoved?.Invoke(hitObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="HitObject"/> to this <see cref="EditorBeatmap{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> to add.</param>
|
||||
public void Add(HitObject hitObject) => Add((T)hitObject);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a <see cref="HitObject"/> from this <see cref="EditorBeatmap{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> to add.</param>
|
||||
public void Remove(HitObject hitObject) => Remove((T)hitObject);
|
||||
}
|
||||
}
|
46
osu.Game/Screens/Edit/EditorWorkingBeatmap.cs
Normal file
46
osu.Game/Screens/Edit/EditorWorkingBeatmap.cs
Normal file
@ -0,0 +1,46 @@
|
||||
// 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.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates a <see cref="WorkingBeatmap"/> while providing an overridden <see cref="Beatmap{TObject}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject"></typeparam>
|
||||
public class EditorWorkingBeatmap<TObject> : IWorkingBeatmap
|
||||
where TObject : HitObject
|
||||
{
|
||||
private readonly Beatmap<TObject> playableBeatmap;
|
||||
private readonly WorkingBeatmap workingBeatmap;
|
||||
|
||||
public EditorWorkingBeatmap(Beatmap<TObject> playableBeatmap, WorkingBeatmap workingBeatmap)
|
||||
{
|
||||
this.playableBeatmap = playableBeatmap;
|
||||
this.workingBeatmap = workingBeatmap;
|
||||
}
|
||||
|
||||
public IBeatmap Beatmap => workingBeatmap.Beatmap;
|
||||
|
||||
public Texture Background => workingBeatmap.Background;
|
||||
|
||||
public Track Track => workingBeatmap.Track;
|
||||
|
||||
public Waveform Waveform => workingBeatmap.Waveform;
|
||||
|
||||
public Storyboard Storyboard => workingBeatmap.Storyboard;
|
||||
|
||||
public Skin Skin => workingBeatmap.Skin;
|
||||
|
||||
public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods) => playableBeatmap;
|
||||
}
|
||||
}
|
36
osu.Game/Screens/Edit/IEditorBeatmap.cs
Normal file
36
osu.Game/Screens/Edit/IEditorBeatmap.cs
Normal file
@ -0,0 +1,36 @@
|
||||
// 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.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for the <see cref="IBeatmap"/> contained by the see <see cref="HitObjectComposer"/>.
|
||||
/// Children of <see cref="HitObjectComposer"/> may resolve the beatmap via <see cref="IEditorBeatmap"/> or <see cref="IEditorBeatmap{T}"/>.
|
||||
/// </summary>
|
||||
public interface IEditorBeatmap : IBeatmap
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="HitObject"/> is added to this <see cref="IEditorBeatmap"/>.
|
||||
/// </summary>
|
||||
event Action<HitObject> HitObjectAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a <see cref="HitObject"/> is removed from this <see cref="IEditorBeatmap"/>.
|
||||
/// </summary>
|
||||
event Action<HitObject> HitObjectRemoved;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for the <see cref="IBeatmap"/> contained by the see <see cref="HitObjectComposer"/>.
|
||||
/// Children of <see cref="HitObjectComposer"/> may resolve the beatmap via <see cref="IEditorBeatmap"/> or <see cref="IEditorBeatmap{T}"/>.
|
||||
/// </summary>
|
||||
public interface IEditorBeatmap<out T> : IEditorBeatmap, IBeatmap<T>
|
||||
where T : HitObject
|
||||
{
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user