mirror of
https://github.com/osukey/osukey.git
synced 2025-08-06 16:13:57 +09:00
Merge remote-tracking branch 'origin/master' into direct-list-view
This commit is contained in:
@ -27,7 +27,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="System.IO.Packaging" Version="4.5.0" />
|
<PackageReference Include="System.IO.Packaging" Version="4.5.0" />
|
||||||
<PackageReference Include="ppy.squirrel.windows" Version="1.8.0.3" />
|
<PackageReference Include="ppy.squirrel.windows" Version="1.8.0.5" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -14,24 +14,20 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ScrollingTestContainer : Container
|
public class ScrollingTestContainer : Container
|
||||||
{
|
{
|
||||||
private readonly ScrollingDirection direction;
|
[Cached(Type = typeof(IScrollingInfo))]
|
||||||
|
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
|
||||||
|
|
||||||
public ScrollingTestContainer(ScrollingDirection direction)
|
public ScrollingTestContainer(ScrollingDirection direction)
|
||||||
{
|
{
|
||||||
this.direction = direction;
|
scrollingInfo.Direction.Value = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
public void Flip() => scrollingInfo.Direction.Value = scrollingInfo.Direction.Value == ScrollingDirection.Up ? ScrollingDirection.Down : ScrollingDirection.Up;
|
||||||
{
|
}
|
||||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
|
||||||
dependencies.CacheAs<IScrollingInfo>(new ScrollingInfo { Direction = { Value = direction }});
|
|
||||||
return dependencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ScrollingInfo : IScrollingInfo
|
public class TestScrollingInfo : IScrollingInfo
|
||||||
{
|
{
|
||||||
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
||||||
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
osu.Game.Rulesets.Mania.Tests/TestCaseEditor.cs
Normal file
32
osu.Game.Rulesets.Mania.Tests/TestCaseEditor.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Game.Rulesets.Mania.Configuration;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestCaseEditor : EditorTestCase
|
||||||
|
{
|
||||||
|
private readonly Bindable<ManiaScrollingDirection> direction = new Bindable<ManiaScrollingDirection>();
|
||||||
|
|
||||||
|
public TestCaseEditor()
|
||||||
|
: base(new ManiaRuleset())
|
||||||
|
{
|
||||||
|
AddStep("upwards scroll", () => direction.Value = ManiaScrollingDirection.Up);
|
||||||
|
AddStep("downwards scroll", () => direction.Value = ManiaScrollingDirection.Down);
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(RulesetConfigCache configCache)
|
||||||
|
{
|
||||||
|
var config = (ManiaConfigManager)configCache.GetConfigFor(Ruleset.Value.CreateInstance());
|
||||||
|
config.BindWith(ManiaSetting.ScrollDirection, direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -46,15 +46,20 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
Spacing = new Vector2(20),
|
Spacing = new Vector2(20),
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
createNoteDisplay(ScrollingDirection.Down),
|
createNoteDisplay(ScrollingDirection.Down, 1, out var note1),
|
||||||
createNoteDisplay(ScrollingDirection.Up),
|
createNoteDisplay(ScrollingDirection.Up, 2, out var note2),
|
||||||
createHoldNoteDisplay(ScrollingDirection.Down),
|
createHoldNoteDisplay(ScrollingDirection.Down, 1, out var holdNote1),
|
||||||
createHoldNoteDisplay(ScrollingDirection.Up),
|
createHoldNoteDisplay(ScrollingDirection.Up, 2, out var holdNote2),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AddAssert("note 1 facing downwards", () => verifyAnchors(note1, Anchor.y2));
|
||||||
|
AddAssert("note 2 facing upwards", () => verifyAnchors(note2, Anchor.y0));
|
||||||
|
AddAssert("hold note 1 facing downwards", () => verifyAnchors(holdNote1, Anchor.y2));
|
||||||
|
AddAssert("hold note 2 facing upwards", () => verifyAnchors(holdNote2, Anchor.y0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Drawable createNoteDisplay(ScrollingDirection direction)
|
private Drawable createNoteDisplay(ScrollingDirection direction, int identifier, out DrawableNote hitObject)
|
||||||
{
|
{
|
||||||
var note = new Note { StartTime = 999999999 };
|
var note = new Note { StartTime = 999999999 };
|
||||||
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
@ -62,24 +67,24 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
return new ScrollingTestContainer(direction)
|
return new ScrollingTestContainer(direction)
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Child = new NoteContainer(direction, $"note, scrolling {direction.ToString().ToLowerInvariant()}")
|
Child = new NoteContainer(direction, $"note {identifier}, scrolling {direction.ToString().ToLowerInvariant()}")
|
||||||
{
|
{
|
||||||
Child = new DrawableNote(note) { AccentColour = Color4.OrangeRed }
|
Child = hitObject = new DrawableNote(note) { AccentColour = Color4.OrangeRed }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Drawable createHoldNoteDisplay(ScrollingDirection direction)
|
private Drawable createHoldNoteDisplay(ScrollingDirection direction, int identifier, out DrawableHoldNote hitObject)
|
||||||
{
|
{
|
||||||
var note = new HoldNote { StartTime = 999999999, Duration = 1000 };
|
var note = new HoldNote { StartTime = 999999999, Duration = 5000 };
|
||||||
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
|
|
||||||
return new ScrollingTestContainer(direction)
|
return new ScrollingTestContainer(direction)
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Child = new NoteContainer(direction, $"hold note, scrolling {direction.ToString().ToLowerInvariant()}")
|
Child = new NoteContainer(direction, $"hold note {identifier}, scrolling {direction.ToString().ToLowerInvariant()}")
|
||||||
{
|
{
|
||||||
Child = new DrawableHoldNote(note)
|
Child = hitObject = new DrawableHoldNote(note)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
AccentColour = Color4.OrangeRed,
|
AccentColour = Color4.OrangeRed,
|
||||||
@ -88,6 +93,12 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool verifyAnchors(DrawableHitObject hitObject, Anchor expectedAnchor)
|
||||||
|
=> hitObject.Anchor.HasFlag(expectedAnchor) && hitObject.Origin.HasFlag(expectedAnchor);
|
||||||
|
|
||||||
|
private bool verifyAnchors(DrawableHoldNote holdNote, Anchor expectedAnchor)
|
||||||
|
=> verifyAnchors((DrawableHitObject)holdNote, expectedAnchor) && holdNote.NestedHitObjects.All(n => verifyAnchors(n, expectedAnchor));
|
||||||
|
|
||||||
private class NoteContainer : Container
|
private class NoteContainer : Container
|
||||||
{
|
{
|
||||||
private readonly Container content;
|
private readonly Container content;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -24,6 +25,8 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
|
|
||||||
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
||||||
|
|
||||||
|
private FillFlowContainer<ScrollingTestContainer> fill;
|
||||||
|
|
||||||
public TestCaseStage()
|
public TestCaseStage()
|
||||||
: base(columns)
|
: base(columns)
|
||||||
{
|
{
|
||||||
@ -32,7 +35,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
Child = new FillFlowContainer
|
Child = fill = new FillFlowContainer<ScrollingTestContainer>
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -54,8 +57,22 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
AddStep("hold note", createHoldNote);
|
AddStep("hold note", createHoldNote);
|
||||||
AddStep("minor bar line", () => createBarLine(false));
|
AddStep("minor bar line", () => createBarLine(false));
|
||||||
AddStep("major bar line", () => createBarLine(true));
|
AddStep("major bar line", () => createBarLine(true));
|
||||||
|
|
||||||
|
AddAssert("check note anchors", () => notesInStageAreAnchored(stages[0], Anchor.TopCentre));
|
||||||
|
AddAssert("check note anchors", () => notesInStageAreAnchored(stages[1], Anchor.BottomCentre));
|
||||||
|
|
||||||
|
AddStep("flip direction", () =>
|
||||||
|
{
|
||||||
|
foreach (var c in fill.Children)
|
||||||
|
c.Flip();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("check note anchors", () => notesInStageAreAnchored(stages[0], Anchor.BottomCentre));
|
||||||
|
AddAssert("check note anchors", () => notesInStageAreAnchored(stages[1], Anchor.TopCentre));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool notesInStageAreAnchored(ManiaStage stage, Anchor anchor) => stage.Columns.SelectMany(c => c.AllHitObjects).All(o => o.Anchor == anchor);
|
||||||
|
|
||||||
private void createNote()
|
private void createNote()
|
||||||
{
|
{
|
||||||
foreach (var stage in stages)
|
foreach (var stage in stages)
|
||||||
@ -101,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Drawable createStage(ScrollingDirection direction, ManiaAction action)
|
private ScrollingTestContainer createStage(ScrollingDirection direction, ManiaAction action)
|
||||||
{
|
{
|
||||||
var specialAction = ManiaAction.Special1;
|
var specialAction = ManiaAction.Special1;
|
||||||
|
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit.Layers.Selection.Overlays
|
||||||
|
{
|
||||||
|
public class HoldNoteMask : HitObjectMask
|
||||||
|
{
|
||||||
|
public new DrawableHoldNote HitObject => (DrawableHoldNote)base.HitObject;
|
||||||
|
|
||||||
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
|
private readonly BodyPiece body;
|
||||||
|
|
||||||
|
public HoldNoteMask(DrawableHoldNote hold)
|
||||||
|
: base(hold)
|
||||||
|
{
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new HoldNoteNoteMask(hold.Head),
|
||||||
|
new HoldNoteNoteMask(hold.Tail),
|
||||||
|
body = new BodyPiece
|
||||||
|
{
|
||||||
|
AccentColour = Color4.Transparent
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours, IScrollingInfo scrollingInfo)
|
||||||
|
{
|
||||||
|
body.BorderColour = colours.Yellow;
|
||||||
|
|
||||||
|
direction.BindTo(scrollingInfo.Direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
Size = HitObject.DrawSize + new Vector2(0, HitObject.Tail.DrawHeight);
|
||||||
|
Position = Parent.ToLocalSpace(HitObject.ScreenSpaceDrawQuad.TopLeft);
|
||||||
|
|
||||||
|
// This is a side-effect of not matching the hitobject's anchors/origins, which is kinda hard to do
|
||||||
|
// When scrolling upwards our origin is already at the top of the head note (which is the intended location),
|
||||||
|
// but when scrolling downwards our origin is at the _bottom_ of the tail note (where we need to be at the _top_ of the tail note)
|
||||||
|
if (direction.Value == ScrollingDirection.Down)
|
||||||
|
Y -= HitObject.Tail.DrawHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HoldNoteNoteMask : NoteMask
|
||||||
|
{
|
||||||
|
public HoldNoteNoteMask(DrawableNote note)
|
||||||
|
: base(note)
|
||||||
|
{
|
||||||
|
Select();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
Anchor = HitObject.Anchor;
|
||||||
|
Origin = HitObject.Origin;
|
||||||
|
|
||||||
|
Position = HitObject.DrawPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: This is temporary, since the note masks don't do anything special yet. In the future they will handle input.
|
||||||
|
public override bool HandleMouseInput => false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit.Layers.Selection.Overlays
|
||||||
|
{
|
||||||
|
public class NoteMask : HitObjectMask
|
||||||
|
{
|
||||||
|
public NoteMask(DrawableNote note)
|
||||||
|
: base(note)
|
||||||
|
{
|
||||||
|
Scale = note.Scale;
|
||||||
|
|
||||||
|
CornerRadius = 5;
|
||||||
|
Masking = true;
|
||||||
|
|
||||||
|
AddInternal(new NotePiece());
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
Colour = colours.Yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
Size = HitObject.DrawSize;
|
||||||
|
Position = Parent.ToLocalSpace(HitObject.ScreenSpaceDrawQuad.TopLeft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
osu.Game.Rulesets.Mania/Edit/ManiaEditPlayfield.cs
Normal file
17
osu.Game.Rulesets.Mania/Edit/ManiaEditPlayfield.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
|
{
|
||||||
|
public class ManiaEditPlayfield : ManiaPlayfield
|
||||||
|
{
|
||||||
|
public ManiaEditPlayfield(List<StageDefinition> stages)
|
||||||
|
: base(stages)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs
Normal file
27
osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using OpenTK;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
|
{
|
||||||
|
public class ManiaEditRulesetContainer : ManiaRulesetContainer
|
||||||
|
{
|
||||||
|
public ManiaEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||||
|
: base(ruleset, beatmap)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Playfield CreatePlayfield() => new ManiaEditPlayfield(Beatmap.Stages)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override Vector2 PlayfieldArea => Vector2.One;
|
||||||
|
}
|
||||||
|
}
|
56
osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs
Normal file
56
osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
using osu.Game.Rulesets.Mania.Edit.Layers.Selection.Overlays;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Rulesets.Mania.Configuration;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
|
{
|
||||||
|
public class ManiaHitObjectComposer : HitObjectComposer
|
||||||
|
{
|
||||||
|
protected new ManiaConfigManager Config => (ManiaConfigManager)base.Config;
|
||||||
|
|
||||||
|
public ManiaHitObjectComposer(Ruleset ruleset)
|
||||||
|
: base(ruleset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
|
{
|
||||||
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
dependencies.CacheAs<IScrollingInfo>(new ManiaScrollingInfo(Config));
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => new ManiaEditRulesetContainer(ruleset, beatmap);
|
||||||
|
|
||||||
|
protected override IReadOnlyList<ICompositionTool> CompositionTools => new ICompositionTool[]
|
||||||
|
{
|
||||||
|
new HitObjectCompositionTool<Note>("Note"),
|
||||||
|
new HitObjectCompositionTool<HoldNote>("Hold"),
|
||||||
|
};
|
||||||
|
|
||||||
|
public override HitObjectMask CreateMaskFor(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case DrawableNote note:
|
||||||
|
return new NoteMask(note);
|
||||||
|
case DrawableHoldNote holdNote:
|
||||||
|
return new HoldNoteMask(holdNote);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateMaskFor(hitObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,9 +19,11 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Configuration;
|
using osu.Game.Rulesets.Configuration;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Configuration;
|
using osu.Game.Rulesets.Mania.Configuration;
|
||||||
using osu.Game.Rulesets.Mania.Difficulty;
|
using osu.Game.Rulesets.Mania.Difficulty;
|
||||||
|
using osu.Game.Rulesets.Mania.Edit;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania
|
namespace osu.Game.Rulesets.Mania
|
||||||
@ -32,6 +34,8 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
|
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
|
||||||
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, Score score) => new ManiaPerformanceCalculator(this, beatmap, score);
|
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, Score score) => new ManiaPerformanceCalculator(this, beatmap, score);
|
||||||
|
|
||||||
|
public override HitObjectComposer CreateHitObjectComposer() => new ManiaHitObjectComposer(this);
|
||||||
|
|
||||||
public override IEnumerable<Mod> ConvertLegacyMods(LegacyMods mods)
|
public override IEnumerable<Mod> ConvertLegacyMods(LegacyMods mods)
|
||||||
{
|
{
|
||||||
if (mods.HasFlag(LegacyMods.Nightcore))
|
if (mods.HasFlag(LegacyMods.Nightcore))
|
||||||
|
@ -21,8 +21,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public override bool DisplayJudgement => false;
|
public override bool DisplayJudgement => false;
|
||||||
|
|
||||||
private readonly DrawableNote head;
|
public readonly DrawableNote Head;
|
||||||
private readonly DrawableNote tail;
|
public readonly DrawableNote Tail;
|
||||||
|
|
||||||
private readonly BodyPiece bodyPiece;
|
private readonly BodyPiece bodyPiece;
|
||||||
|
|
||||||
@ -57,12 +57,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
HoldStartTime = () => holdStartTime
|
HoldStartTime = () => holdStartTime
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
head = new DrawableHeadNote(this)
|
Head = new DrawableHeadNote(this)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre
|
Origin = Anchor.TopCentre
|
||||||
},
|
},
|
||||||
tail = new DrawableTailNote(this)
|
Tail = new DrawableTailNote(this)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre
|
Origin = Anchor.TopCentre
|
||||||
@ -72,8 +72,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
foreach (var tick in tickContainer)
|
foreach (var tick in tickContainer)
|
||||||
AddNested(tick);
|
AddNested(tick);
|
||||||
|
|
||||||
AddNested(head);
|
AddNested(Head);
|
||||||
AddNested(tail);
|
AddNested(Tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDirectionChanged(ScrollingDirection direction)
|
protected override void OnDirectionChanged(ScrollingDirection direction)
|
||||||
@ -91,15 +91,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
|
|
||||||
bodyPiece.AccentColour = value;
|
bodyPiece.AccentColour = value;
|
||||||
head.AccentColour = value;
|
Head.AccentColour = value;
|
||||||
tail.AccentColour = value;
|
Tail.AccentColour = value;
|
||||||
tickContainer.ForEach(t => t.AccentColour = value);
|
tickContainer.ForEach(t => t.AccentColour = value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||||
{
|
{
|
||||||
if (tail.AllJudged)
|
if (Tail.AllJudged)
|
||||||
AddJudgement(new HoldNoteJudgement { Result = HitResult.Perfect });
|
AddJudgement(new HoldNoteJudgement { Result = HitResult.Perfect });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,8 +108,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
// Make the body piece not lie under the head note
|
// Make the body piece not lie under the head note
|
||||||
bodyPiece.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * head.Height / 2;
|
bodyPiece.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2;
|
||||||
bodyPiece.Height = DrawHeight - head.Height / 2 + tail.Height / 2;
|
bodyPiece.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPressed(ManiaAction action)
|
public bool OnPressed(ManiaAction action)
|
||||||
@ -141,7 +141,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
holdStartTime = null;
|
holdStartTime = null;
|
||||||
|
|
||||||
// If the key has been released too early, the user should not receive full score for the release
|
// If the key has been released too early, the user should not receive full score for the release
|
||||||
if (!tail.IsHit)
|
if (!Tail.IsHit)
|
||||||
hasBroken = true;
|
hasBroken = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -8,7 +8,7 @@ using osu.Game.Rulesets.Objects.Drawables;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
internal class DrawableManiaJudgement : DrawableJudgement
|
public class DrawableManiaJudgement : DrawableJudgement
|
||||||
{
|
{
|
||||||
public DrawableManiaJudgement(Judgement judgement, DrawableHitObject judgedObject)
|
public DrawableManiaJudgement(Judgement judgement, DrawableHitObject judgedObject)
|
||||||
: base(judgement, judgedObject)
|
: base(judgement, judgedObject)
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
|
||||||
using osu.Game.Rulesets.Mania.Configuration;
|
using osu.Game.Rulesets.Mania.Configuration;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
public class ManiaPlayfield : ManiaScrollingPlayfield
|
public class ManiaPlayfield : ManiaScrollingPlayfield
|
||||||
{
|
{
|
||||||
public List<Column> Columns => stages.SelectMany(x => x.Columns).ToList();
|
|
||||||
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
||||||
|
|
||||||
public ManiaPlayfield(List<StageDefinition> stageDefinitions)
|
public ManiaPlayfield(List<StageDefinition> stageDefinitions)
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
@ -35,8 +34,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
public IEnumerable<BarLine> BarLines;
|
public IEnumerable<BarLine> BarLines;
|
||||||
|
|
||||||
private readonly Bindable<ManiaScrollingDirection> configDirection = new Bindable<ManiaScrollingDirection>();
|
protected new ManiaConfigManager Config => (ManiaConfigManager)base.Config;
|
||||||
private ScrollingInfo scrollingInfo;
|
|
||||||
|
|
||||||
public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||||
: base(ruleset, beatmap)
|
: base(ruleset, beatmap)
|
||||||
@ -73,9 +71,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
BarLines.ForEach(Playfield.Add);
|
BarLines.ForEach(Playfield.Add);
|
||||||
|
|
||||||
((ManiaConfigManager)Config).BindWith(ManiaSetting.ScrollDirection, configDirection);
|
|
||||||
configDirection.BindValueChanged(d => scrollingInfo.Direction.Value = (ScrollingDirection)d, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
@ -83,11 +78,14 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
dependencies.CacheAs<IScrollingInfo>(scrollingInfo = new ScrollingInfo());
|
|
||||||
|
if (dependencies.Get<ManiaScrollingInfo>() == null)
|
||||||
|
dependencies.CacheAs<IScrollingInfo>(new ManiaScrollingInfo(Config));
|
||||||
|
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
|
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -115,11 +113,5 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
protected override Vector2 PlayfieldArea => new Vector2(1, 0.8f);
|
protected override Vector2 PlayfieldArea => new Vector2(1, 0.8f);
|
||||||
|
|
||||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay);
|
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay);
|
||||||
|
|
||||||
private class ScrollingInfo : IScrollingInfo
|
|
||||||
{
|
|
||||||
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
|
||||||
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
osu.Game.Rulesets.Mania/UI/ManiaScrollingInfo.cs
Normal file
23
osu.Game.Rulesets.Mania/UI/ManiaScrollingInfo.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Game.Rulesets.Mania.Configuration;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
|
{
|
||||||
|
public class ManiaScrollingInfo : IScrollingInfo
|
||||||
|
{
|
||||||
|
private readonly Bindable<ManiaScrollingDirection> configDirection = new Bindable<ManiaScrollingDirection>();
|
||||||
|
|
||||||
|
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
||||||
|
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
||||||
|
|
||||||
|
public ManiaScrollingInfo(ManiaConfigManager config)
|
||||||
|
{
|
||||||
|
config.BindWith(ManiaSetting.ScrollDirection, configDirection);
|
||||||
|
configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A collection of <see cref="Column"/>s.
|
/// A collection of <see cref="Column"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class ManiaStage : ManiaScrollingPlayfield
|
public class ManiaStage : ManiaScrollingPlayfield
|
||||||
{
|
{
|
||||||
public const float HIT_TARGET_POSITION = 50;
|
public const float HIT_TARGET_POSITION = 50;
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Overlays.Mods;
|
using osu.Game.Overlays.Mods;
|
||||||
@ -13,11 +12,11 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Rulesets.Osu;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Overlays.Mods.Sections;
|
using osu.Game.Overlays.Mods.Sections;
|
||||||
using osu.Game.Rulesets.Mania;
|
|
||||||
using osu.Game.Rulesets.Mania.Mods;
|
using osu.Game.Rulesets.Mania.Mods;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
@ -50,11 +49,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
private void load(RulesetStore rulesets)
|
private void load(RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
this.rulesets = rulesets;
|
this.rulesets = rulesets;
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
Add(modSelect = new TestModSelectOverlay
|
Add(modSelect = new TestModSelectOverlay
|
||||||
{
|
{
|
||||||
@ -71,34 +65,25 @@ namespace osu.Game.Tests.Visual
|
|||||||
Position = new Vector2(0, 25),
|
Position = new Vector2(0, 25),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modDisplay.Current.UnbindBindings();
|
||||||
modDisplay.Current.BindTo(modSelect.SelectedMods);
|
modDisplay.Current.BindTo(modSelect.SelectedMods);
|
||||||
|
|
||||||
AddStep("Toggle", modSelect.ToggleVisibility);
|
|
||||||
AddStep("Hide", modSelect.Hide);
|
|
||||||
AddStep("Show", modSelect.Show);
|
AddStep("Show", modSelect.Show);
|
||||||
|
AddStep("Toggle", modSelect.ToggleVisibility);
|
||||||
foreach (var rulesetInfo in rulesets.AvailableRulesets)
|
AddStep("Toggle", modSelect.ToggleVisibility);
|
||||||
{
|
|
||||||
Ruleset ruleset = rulesetInfo.CreateInstance();
|
|
||||||
AddStep($"switch to {ruleset.Description}", () => Ruleset.Value = rulesetInfo);
|
|
||||||
|
|
||||||
switch (ruleset)
|
|
||||||
{
|
|
||||||
case OsuRuleset or:
|
|
||||||
testOsuMods(or);
|
|
||||||
break;
|
|
||||||
case ManiaRuleset mr:
|
|
||||||
testManiaMods(mr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testOsuMods(OsuRuleset ruleset)
|
[Test]
|
||||||
|
public void TestOsuMods()
|
||||||
{
|
{
|
||||||
var easierMods = ruleset.GetModsFor(ModType.DifficultyReduction);
|
var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 0);
|
||||||
var harderMods = ruleset.GetModsFor(ModType.DifficultyIncrease);
|
AddStep("change ruleset", () => { Ruleset.Value = ruleset; });
|
||||||
var assistMods = ruleset.GetModsFor(ModType.Automation);
|
|
||||||
|
var instance = ruleset.CreateInstance();
|
||||||
|
|
||||||
|
var easierMods = instance.GetModsFor(ModType.DifficultyReduction);
|
||||||
|
var harderMods = instance.GetModsFor(ModType.DifficultyIncrease);
|
||||||
|
var assistMods = instance.GetModsFor(ModType.Automation);
|
||||||
|
|
||||||
var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail);
|
var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail);
|
||||||
var hiddenMod = harderMods.FirstOrDefault(m => m is OsuModHidden);
|
var hiddenMod = harderMods.FirstOrDefault(m => m is OsuModHidden);
|
||||||
@ -120,9 +105,40 @@ namespace osu.Game.Tests.Visual
|
|||||||
testUnimplementedMod(autoPilotMod);
|
testUnimplementedMod(autoPilotMod);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testManiaMods(ManiaRuleset ruleset)
|
[Test]
|
||||||
|
public void TestManiaMods()
|
||||||
{
|
{
|
||||||
testRankedText(ruleset.GetModsFor(ModType.Conversion).First(m => m is ManiaModRandom));
|
var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 3);
|
||||||
|
AddStep("change ruleset", () => { Ruleset.Value = ruleset; });
|
||||||
|
|
||||||
|
testRankedText(ruleset.CreateInstance().GetModsFor(ModType.Conversion).First(m => m is ManiaModRandom));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestRulesetChanges()
|
||||||
|
{
|
||||||
|
var rulesetOsu = rulesets.AvailableRulesets.First(r => r.ID == 0);
|
||||||
|
var rulesetMania = rulesets.AvailableRulesets.First(r => r.ID == 3);
|
||||||
|
|
||||||
|
AddStep("change ruleset to null", () => { Ruleset.Value = null; });
|
||||||
|
|
||||||
|
var instance = rulesetOsu.CreateInstance();
|
||||||
|
var easierMods = instance.GetModsFor(ModType.DifficultyReduction);
|
||||||
|
var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail);
|
||||||
|
|
||||||
|
AddStep("set mods externally", () => { modDisplay.Current.Value = new[] { noFailMod }; });
|
||||||
|
|
||||||
|
AddStep("change ruleset to osu", () => { Ruleset.Value = rulesetOsu; });
|
||||||
|
|
||||||
|
AddAssert("ensure mods still selected", () => modDisplay.Current.Value.Single(m => m is OsuModNoFail) != null);
|
||||||
|
|
||||||
|
AddStep("change ruleset to mania", () => { Ruleset.Value = rulesetMania; });
|
||||||
|
|
||||||
|
AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any(m => m is OsuModNoFail));
|
||||||
|
|
||||||
|
AddStep("change ruleset to osu", () => { Ruleset.Value = rulesetOsu; });
|
||||||
|
|
||||||
|
AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testSingleMod(Mod mod)
|
private void testSingleMod(Mod mod)
|
||||||
@ -237,6 +253,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private class TestModSelectOverlay : ModSelectOverlay
|
private class TestModSelectOverlay : ModSelectOverlay
|
||||||
{
|
{
|
||||||
|
public new Bindable<IEnumerable<Mod>> SelectedMods => base.SelectedMods;
|
||||||
|
|
||||||
public ModButton GetModButton(Mod mod)
|
public ModButton GetModButton(Mod mod)
|
||||||
{
|
{
|
||||||
var section = ModSectionsContainer.Children.Single(s => s.ModType == mod.Type);
|
var section = ModSectionsContainer.Children.Single(s => s.ModType == mod.Type);
|
||||||
|
@ -1,25 +1,61 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Threading;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
public class TestCasePlayerLoader : OsuTestCase
|
public class TestCasePlayerLoader : ManualInputManagerTestCase
|
||||||
{
|
{
|
||||||
|
private PlayerLoader loader;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase game)
|
private void load(OsuGameBase game)
|
||||||
{
|
{
|
||||||
Beatmap.Value = new DummyWorkingBeatmap(game);
|
Beatmap.Value = new DummyWorkingBeatmap(game);
|
||||||
|
|
||||||
AddStep("load dummy beatmap", () => Add(new PlayerLoader(new Player
|
AddStep("load dummy beatmap", () => Add(loader = new PlayerLoader(new Player
|
||||||
{
|
{
|
||||||
AllowPause = false,
|
AllowPause = false,
|
||||||
AllowLeadIn = false,
|
AllowLeadIn = false,
|
||||||
AllowResults = false,
|
AllowResults = false,
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
|
||||||
|
|
||||||
|
AddUntilStep(() => !loader.IsCurrentScreen, "wait for no longer current");
|
||||||
|
|
||||||
|
AddStep("load slow dummy beatmap", () =>
|
||||||
|
{
|
||||||
|
SlowLoadPlayer slow;
|
||||||
|
|
||||||
|
Add(loader = new PlayerLoader(slow = new SlowLoadPlayer
|
||||||
|
{
|
||||||
|
AllowPause = false,
|
||||||
|
AllowLeadIn = false,
|
||||||
|
AllowResults = false,
|
||||||
|
}));
|
||||||
|
|
||||||
|
Scheduler.AddDelayed(() => slow.Ready = true, 5000);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep(() => !loader.IsCurrentScreen, "wait for no longer current");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class SlowLoadPlayer : Player
|
||||||
|
{
|
||||||
|
public bool Ready;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
while (!Ready)
|
||||||
|
Thread.Sleep(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,9 @@ namespace osu.Game
|
|||||||
private readonly List<OverlayContainer> overlays = new List<OverlayContainer>();
|
private readonly List<OverlayContainer> overlays = new List<OverlayContainer>();
|
||||||
|
|
||||||
// todo: move this to SongSelect once Screen has the ability to unsuspend.
|
// todo: move this to SongSelect once Screen has the ability to unsuspend.
|
||||||
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new List<Mod>());
|
[Cached]
|
||||||
|
[Cached(Type = typeof(IBindable<IEnumerable<Mod>>))]
|
||||||
|
private readonly Bindable<IEnumerable<Mod>> selectedMods = new Bindable<IEnumerable<Mod>>(new Mod[] { });
|
||||||
|
|
||||||
public OsuGame(string[] args = null)
|
public OsuGame(string[] args = null)
|
||||||
{
|
{
|
||||||
|
@ -39,9 +39,39 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
protected readonly FillFlowContainer<ModSection> ModSectionsContainer;
|
protected readonly FillFlowContainer<ModSection> ModSectionsContainer;
|
||||||
|
|
||||||
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>();
|
protected readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new Mod[] { });
|
||||||
|
|
||||||
public readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
protected readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(true)]
|
||||||
|
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IEnumerable<Mod>> selectedMods)
|
||||||
|
{
|
||||||
|
LowMultiplierColour = colours.Red;
|
||||||
|
HighMultiplierColour = colours.Green;
|
||||||
|
UnrankedLabel.Colour = colours.Blue;
|
||||||
|
|
||||||
|
Ruleset.BindTo(ruleset);
|
||||||
|
if (selectedMods != null) SelectedMods.BindTo(selectedMods);
|
||||||
|
|
||||||
|
sampleOn = audio.Sample.Get(@"UI/check-on");
|
||||||
|
sampleOff = audio.Sample.Get(@"UI/check-off");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Ruleset.BindValueChanged(rulesetChanged, true);
|
||||||
|
SelectedMods.BindValueChanged(selectedModsChanged, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
Ruleset.UnbindAll();
|
||||||
|
SelectedMods.UnbindAll();
|
||||||
|
}
|
||||||
|
|
||||||
private void rulesetChanged(RulesetInfo newRuleset)
|
private void rulesetChanged(RulesetInfo newRuleset)
|
||||||
{
|
{
|
||||||
@ -51,33 +81,16 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
foreach (ModSection section in ModSectionsContainer.Children)
|
foreach (ModSection section in ModSectionsContainer.Children)
|
||||||
section.Mods = instance.GetModsFor(section.ModType);
|
section.Mods = instance.GetModsFor(section.ModType);
|
||||||
|
|
||||||
|
// attempt to re-select any already selected mods.
|
||||||
|
// this may be the first time we are receiving the ruleset, in which case they will still match.
|
||||||
|
selectedModsChanged(SelectedMods.Value);
|
||||||
|
|
||||||
|
// write the mods back to the SelectedMods bindable in the case a change was not applicable.
|
||||||
|
// this generally isn't required as the previous line will perform deselection; just here for safety.
|
||||||
refreshSelectedMods();
|
refreshSelectedMods();
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio)
|
|
||||||
{
|
|
||||||
SelectedMods.ValueChanged += selectedModsChanged;
|
|
||||||
|
|
||||||
LowMultiplierColour = colours.Red;
|
|
||||||
HighMultiplierColour = colours.Green;
|
|
||||||
UnrankedLabel.Colour = colours.Blue;
|
|
||||||
|
|
||||||
Ruleset.BindTo(ruleset);
|
|
||||||
Ruleset.BindValueChanged(rulesetChanged, true);
|
|
||||||
|
|
||||||
sampleOn = audio.Sample.Get(@"UI/check-on");
|
|
||||||
sampleOff = audio.Sample.Get(@"UI/check-off");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
|
||||||
{
|
|
||||||
base.Dispose(isDisposing);
|
|
||||||
|
|
||||||
Ruleset.UnbindAll();
|
|
||||||
SelectedMods.UnbindAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectedModsChanged(IEnumerable<Mod> obj)
|
private void selectedModsChanged(IEnumerable<Mod> obj)
|
||||||
{
|
{
|
||||||
foreach (ModSection section in ModSectionsContainer.Children)
|
foreach (ModSection section in ModSectionsContainer.Children)
|
||||||
@ -176,10 +189,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
refreshSelectedMods();
|
refreshSelectedMods();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshSelectedMods()
|
private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray();
|
||||||
{
|
|
||||||
SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModSelectOverlay()
|
public ModSelectOverlay()
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Configuration;
|
||||||
using osu.Game.Rulesets.Edit.Tools;
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
@ -23,12 +24,15 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
{
|
{
|
||||||
private readonly Ruleset ruleset;
|
private readonly Ruleset ruleset;
|
||||||
|
|
||||||
|
public IEnumerable<DrawableHitObject> HitObjects => rulesetContainer.Playfield.AllHitObjects;
|
||||||
|
|
||||||
protected ICompositionTool CurrentTool { get; private set; }
|
protected ICompositionTool CurrentTool { get; private set; }
|
||||||
|
protected IRulesetConfigManager Config { get; private set; }
|
||||||
|
|
||||||
|
private readonly List<Container> layerContainers = new List<Container>();
|
||||||
|
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||||
|
|
||||||
private RulesetContainer rulesetContainer;
|
private RulesetContainer rulesetContainer;
|
||||||
private readonly List<Container> layerContainers = new List<Container>();
|
|
||||||
|
|
||||||
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
|
||||||
|
|
||||||
protected HitObjectComposer(Ruleset ruleset)
|
protected HitObjectComposer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
@ -60,7 +64,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
};
|
};
|
||||||
|
|
||||||
var layerAboveRuleset = CreateLayerContainer();
|
var layerAboveRuleset = CreateLayerContainer();
|
||||||
layerAboveRuleset.Child = new HitObjectMaskLayer(rulesetContainer.Playfield, this);
|
layerAboveRuleset.Child = new HitObjectMaskLayer();
|
||||||
|
|
||||||
layerContainers.Add(layerBelowRuleset);
|
layerContainers.Add(layerBelowRuleset);
|
||||||
layerContainers.Add(layerAboveRuleset);
|
layerContainers.Add(layerAboveRuleset);
|
||||||
@ -110,6 +114,16 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
toolboxCollection.Items[0].Select();
|
toolboxCollection.Items[0].Select();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
@ -8,6 +8,16 @@ namespace osu.Game.Rulesets.Edit.Tools
|
|||||||
public class HitObjectCompositionTool<T> : ICompositionTool
|
public class HitObjectCompositionTool<T> : ICompositionTool
|
||||||
where T : HitObject
|
where T : HitObject
|
||||||
{
|
{
|
||||||
public string Name => typeof(T).Name;
|
public string Name { get; }
|
||||||
|
|
||||||
|
public HitObjectCompositionTool()
|
||||||
|
: this(typeof(T).Name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public HitObjectCompositionTool(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.UI
|
namespace osu.Game.Rulesets.UI
|
||||||
@ -12,15 +15,21 @@ namespace osu.Game.Rulesets.UI
|
|||||||
public abstract class Playfield : ScalableContainer
|
public abstract class Playfield : ScalableContainer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The HitObjects contained in this Playfield.
|
/// The <see cref="DrawableHitObject"/> contained in this Playfield.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public HitObjectContainer HitObjects { get; private set; }
|
public HitObjectContainer HitObjects { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All the <see cref="Playfield"/>s nested inside this playfield.
|
/// All the <see cref="DrawableHitObject"/>s contained in this <see cref="Playfield"/> and all <see cref="NestedPlayfields"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<Playfield> NestedPlayfields => nestedPlayfields;
|
public IEnumerable<DrawableHitObject> AllHitObjects => HitObjects?.Objects.Concat(NestedPlayfields.SelectMany(p => p.AllHitObjects)) ?? Enumerable.Empty<DrawableHitObject>();
|
||||||
private List<Playfield> nestedPlayfields;
|
|
||||||
|
/// <summary>
|
||||||
|
/// All <see cref="Playfield"/>s nested inside this <see cref="Playfield"/>.
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<Playfield> NestedPlayfields => nestedPlayfields.IsValueCreated ? nestedPlayfields.Value : Enumerable.Empty<Playfield>();
|
||||||
|
|
||||||
|
private readonly Lazy<List<Playfield>> nestedPlayfields = new Lazy<List<Playfield>>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether judgements should be displayed by this and and all nested <see cref="Playfield"/>s.
|
/// Whether judgements should be displayed by this and and all nested <see cref="Playfield"/>s.
|
||||||
@ -54,7 +63,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs post-processing tasks (if any) after all DrawableHitObjects are loaded into this Playfield.
|
/// Performs post-processing tasks (if any) after all DrawableHitObjects are loaded into this Playfield.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void PostProcess() => nestedPlayfields?.ForEach(p => p.PostProcess());
|
public virtual void PostProcess() => NestedPlayfields.ForEach(p => p.PostProcess());
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a DrawableHitObject to this Playfield.
|
/// Adds a DrawableHitObject to this Playfield.
|
||||||
@ -75,12 +84,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// <param name="otherPlayfield">The <see cref="Playfield"/> to add.</param>
|
/// <param name="otherPlayfield">The <see cref="Playfield"/> to add.</param>
|
||||||
protected void AddNested(Playfield otherPlayfield)
|
protected void AddNested(Playfield otherPlayfield)
|
||||||
{
|
{
|
||||||
if (nestedPlayfields == null)
|
|
||||||
nestedPlayfields = new List<Playfield>();
|
|
||||||
|
|
||||||
nestedPlayfields.Add(otherPlayfield);
|
|
||||||
|
|
||||||
otherPlayfield.DisplayJudgements.BindTo(DisplayJudgements);
|
otherPlayfield.DisplayJudgements.BindTo(DisplayJudgements);
|
||||||
|
nestedPlayfields.Value.Add(otherPlayfield);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -9,30 +8,24 @@ using osu.Framework.Input.EventArgs;
|
|||||||
using osu.Framework.Input.States;
|
using osu.Framework.Input.States;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Screens.Compose.Layers
|
namespace osu.Game.Screens.Edit.Screens.Compose.Layers
|
||||||
{
|
{
|
||||||
public class HitObjectMaskLayer : CompositeDrawable
|
public class HitObjectMaskLayer : CompositeDrawable
|
||||||
{
|
{
|
||||||
private readonly Playfield playfield;
|
|
||||||
private readonly HitObjectComposer composer;
|
|
||||||
|
|
||||||
private MaskContainer maskContainer;
|
private MaskContainer maskContainer;
|
||||||
|
private HitObjectComposer composer;
|
||||||
|
|
||||||
public HitObjectMaskLayer(Playfield playfield, HitObjectComposer composer)
|
public HitObjectMaskLayer()
|
||||||
{
|
{
|
||||||
// we need the playfield as HitObjects may not be initialised until its BDL.
|
|
||||||
this.playfield = playfield;
|
|
||||||
|
|
||||||
this.composer = composer;
|
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(HitObjectComposer composer)
|
||||||
{
|
{
|
||||||
|
this.composer = composer;
|
||||||
|
|
||||||
maskContainer = new MaskContainer();
|
maskContainer = new MaskContainer();
|
||||||
|
|
||||||
var maskSelection = composer.CreateMaskSelection();
|
var maskSelection = composer.CreateMaskSelection();
|
||||||
@ -55,7 +48,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Layers
|
|||||||
dragLayer.CreateProxy()
|
dragLayer.CreateProxy()
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var obj in playfield.HitObjects.Objects)
|
foreach (var obj in composer.HitObjects)
|
||||||
addMask(obj);
|
addMask(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,18 +70,5 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Layers
|
|||||||
|
|
||||||
maskContainer.Add(mask);
|
maskContainer.Add(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes the mask for a <see cref="DrawableHitObject"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to remove the mask for.</param>
|
|
||||||
private void removeMask(DrawableHitObject hitObject)
|
|
||||||
{
|
|
||||||
var mask = maskContainer.FirstOrDefault(h => h.HitObject == hitObject);
|
|
||||||
if (mask == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
maskContainer.Remove(mask);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,11 @@ using osu.Framework.Threading;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using osu.Game.Screens.Play.PlayerSettings;
|
using osu.Game.Screens.Play.PlayerSettings;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
@ -69,21 +71,25 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
loadTask = LoadComponentAsync(player);
|
loadTask = LoadComponentAsync(player, playerLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void playerLoaded(Player player) => info.Loading = false;
|
||||||
|
|
||||||
protected override void OnResuming(Screen last)
|
protected override void OnResuming(Screen last)
|
||||||
{
|
{
|
||||||
base.OnResuming(last);
|
base.OnResuming(last);
|
||||||
|
|
||||||
contentIn();
|
contentIn();
|
||||||
|
|
||||||
|
info.Loading = true;
|
||||||
|
|
||||||
//we will only be resumed if the player has requested a re-run (see ValidForResume setting above)
|
//we will only be resumed if the player has requested a re-run (see ValidForResume setting above)
|
||||||
loadTask = LoadComponentAsync(player = new Player
|
loadTask = LoadComponentAsync(player = new Player
|
||||||
{
|
{
|
||||||
RestartCount = player.RestartCount + 1,
|
RestartCount = player.RestartCount + 1,
|
||||||
RestartRequested = player.RestartRequested,
|
RestartRequested = player.RestartRequested,
|
||||||
});
|
}, playerLoaded);
|
||||||
|
|
||||||
this.Delay(400).Schedule(pushWhenLoaded);
|
this.Delay(400).Schedule(pushWhenLoaded);
|
||||||
}
|
}
|
||||||
@ -258,6 +264,25 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly WorkingBeatmap beatmap;
|
private readonly WorkingBeatmap beatmap;
|
||||||
|
private LoadingAnimation loading;
|
||||||
|
private Sprite backgroundSprite;
|
||||||
|
|
||||||
|
public bool Loading
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
loading.Show();
|
||||||
|
backgroundSprite.FadeColour(OsuColour.Gray(0.5f), 400, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loading.Hide();
|
||||||
|
backgroundSprite.FadeColour(Color4.White, 400, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public BeatmapMetadataDisplay(WorkingBeatmap beatmap)
|
public BeatmapMetadataDisplay(WorkingBeatmap beatmap)
|
||||||
{
|
{
|
||||||
@ -304,9 +329,9 @@ namespace osu.Game.Screens.Play
|
|||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
CornerRadius = 10,
|
CornerRadius = 10,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
Children = new[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Sprite
|
backgroundSprite = new Sprite
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Texture = beatmap?.Background,
|
Texture = beatmap?.Background,
|
||||||
@ -314,6 +339,7 @@ namespace osu.Game.Screens.Play
|
|||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
},
|
},
|
||||||
|
loading = new LoadingAnimation { Scale = new Vector2(1.3f) }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
@ -341,6 +367,8 @@ namespace osu.Game.Screens.Play
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,13 +50,14 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
private SampleChannel sampleConfirm;
|
private SampleChannel sampleConfirm;
|
||||||
|
|
||||||
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>(new List<Mod>());
|
[Cached]
|
||||||
|
[Cached(Type = typeof(IBindable<IEnumerable<Mod>>))]
|
||||||
|
private readonly Bindable<IEnumerable<Mod>> selectedMods = new Bindable<IEnumerable<Mod>>(new Mod[] { });
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu)
|
private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, Bindable<IEnumerable<Mod>> selectedMods)
|
||||||
{
|
{
|
||||||
if (osu != null) SelectedMods.BindTo(osu.SelectedMods);
|
if (selectedMods != null) this.selectedMods.BindTo(selectedMods);
|
||||||
modSelect.SelectedMods.BindTo(SelectedMods);
|
|
||||||
|
|
||||||
sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection");
|
sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection");
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
protected override void UpdateBeatmap(WorkingBeatmap beatmap)
|
protected override void UpdateBeatmap(WorkingBeatmap beatmap)
|
||||||
{
|
{
|
||||||
beatmap.Mods.BindTo(SelectedMods);
|
beatmap.Mods.BindTo(selectedMods);
|
||||||
|
|
||||||
base.UpdateBeatmap(beatmap);
|
base.UpdateBeatmap(beatmap);
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ namespace osu.Game.Screens.Select
|
|||||||
if (Beatmap.Value.Track != null)
|
if (Beatmap.Value.Track != null)
|
||||||
Beatmap.Value.Track.Looping = false;
|
Beatmap.Value.Track.Looping = false;
|
||||||
|
|
||||||
SelectedMods.UnbindAll();
|
selectedMods.UnbindAll();
|
||||||
Beatmap.Value.Mods.Value = new Mod[] { };
|
Beatmap.Value.Mods.Value = new Mod[] { };
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -147,10 +148,10 @@ namespace osu.Game.Screens.Select
|
|||||||
var auto = Ruleset.Value.CreateInstance().GetAutoplayMod();
|
var auto = Ruleset.Value.CreateInstance().GetAutoplayMod();
|
||||||
var autoType = auto.GetType();
|
var autoType = auto.GetType();
|
||||||
|
|
||||||
var mods = modSelect.SelectedMods.Value;
|
var mods = selectedMods.Value;
|
||||||
if (mods.All(m => m.GetType() != autoType))
|
if (mods.All(m => m.GetType() != autoType))
|
||||||
{
|
{
|
||||||
modSelect.SelectedMods.Value = mods.Append(auto);
|
selectedMods.Value = mods.Append(auto);
|
||||||
removeAutoModOnResume = true;
|
removeAutoModOnResume = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2018.803.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2018.806.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
||||||
|
Reference in New Issue
Block a user